The regex only matched "N passed in X.XXs" but pytest can output "N passed, M warnings in X.XXs". Updated regex to handle both. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
141 lines
4.3 KiB
Python
141 lines
4.3 KiB
Python
"""Unit tests for scripts/check_test_speed.py."""
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import click
|
|
import pytest
|
|
from click.testing import CliRunner
|
|
|
|
from scripts.check_test_speed import (
|
|
DEFAULT_MAX_SECONDS,
|
|
TEST_COMMAND,
|
|
check_speed,
|
|
cli,
|
|
parse_duration,
|
|
run_tests,
|
|
)
|
|
|
|
|
|
class TestRunTests:
|
|
@patch("scripts.check_test_speed.subprocess.run")
|
|
def test_run_tests_returns_stdout_stderr(self, mock_run: MagicMock) -> None:
|
|
mock_run.return_value = MagicMock(stdout="out", stderr="err", returncode=0)
|
|
stdout, stderr = run_tests()
|
|
assert stdout == "out"
|
|
assert stderr == "err"
|
|
mock_run.assert_called_once_with(
|
|
TEST_COMMAND,
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
|
|
|
|
class TestParseDuration:
|
|
def test_parses_valid_line(self) -> None:
|
|
assert parse_duration("234 passed in 0.70s") == 0.70
|
|
|
|
def test_parses_with_warnings(self) -> None:
|
|
assert parse_duration("293 passed, 1 warning in 0.45s") == 0.45
|
|
|
|
def test_parses_multiline_output(self) -> None:
|
|
output = "some header\n234 passed in 1.23s\nfooter"
|
|
assert parse_duration(output) == 1.23
|
|
|
|
def test_raises_when_no_timing_line(self) -> None:
|
|
with pytest.raises(click.ClickException) as exc:
|
|
parse_duration("no timing here")
|
|
assert "Could not parse" in str(exc.value)
|
|
|
|
|
|
class TestCheckSpeed:
|
|
def test_under_budget_passes(self) -> None:
|
|
check_speed(1.0, 2.0) # should not raise
|
|
|
|
def test_exact_budget_passes(self) -> None:
|
|
check_speed(2.0, 2.0) # should not raise
|
|
|
|
def test_over_budget_raises(self) -> None:
|
|
with pytest.raises(click.ClickException) as exc:
|
|
check_speed(2.1, 2.0)
|
|
msg = str(exc.value)
|
|
assert "too slow" in msg.lower()
|
|
assert "2.10s" in msg
|
|
assert "max allowed: 2.0s" in msg
|
|
|
|
|
|
def test_main_module_block() -> None:
|
|
import scripts.check_test_speed as cts
|
|
|
|
with patch.object(cts, "cli") as mock_cli:
|
|
with patch.object(cts, "__name__", "__main__"):
|
|
cts.cli([])
|
|
mock_cli.assert_called_once_with([])
|
|
|
|
|
|
class TestMain:
|
|
@patch("scripts.check_test_speed.run_tests")
|
|
@patch("scripts.check_test_speed.parse_duration")
|
|
@patch("scripts.check_test_speed.check_speed")
|
|
def test_successful_run(
|
|
self,
|
|
mock_check: MagicMock,
|
|
mock_parse: MagicMock,
|
|
mock_run: MagicMock,
|
|
) -> None:
|
|
mock_run.return_value = ("stdout\n", "stderr\n")
|
|
mock_parse.return_value = 1.5
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, [])
|
|
assert result.exit_code == 0
|
|
assert "1.50s" in result.output
|
|
assert "under 2.0s limit" in result.output
|
|
mock_run.assert_called_once()
|
|
mock_parse.assert_called_once_with("stdout\n\nstderr\n")
|
|
mock_check.assert_called_once_with(1.5, DEFAULT_MAX_SECONDS)
|
|
|
|
@patch("scripts.check_test_speed.run_tests")
|
|
@patch("scripts.check_test_speed.parse_duration")
|
|
def test_slow_tests_exit(
|
|
self,
|
|
mock_parse: MagicMock,
|
|
mock_run: MagicMock,
|
|
) -> None:
|
|
mock_run.return_value = ("out\n", "err\n")
|
|
mock_parse.return_value = 3.0
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, [])
|
|
assert result.exit_code == 1
|
|
assert "too slow" in result.output.lower()
|
|
|
|
@patch("scripts.check_test_speed.run_tests")
|
|
def test_parse_failure_exits(
|
|
self,
|
|
mock_run: MagicMock,
|
|
) -> None:
|
|
mock_run.return_value = ("bad output\n", "")
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, [])
|
|
assert result.exit_code == 1
|
|
assert "Could not parse" in result.output
|
|
|
|
@patch("scripts.check_test_speed.run_tests")
|
|
@patch("scripts.check_test_speed.parse_duration")
|
|
@patch("scripts.check_test_speed.check_speed")
|
|
def test_custom_max_seconds(
|
|
self,
|
|
mock_check: MagicMock,
|
|
mock_parse: MagicMock,
|
|
mock_run: MagicMock,
|
|
) -> None:
|
|
mock_run.return_value = ("out\n", "err\n")
|
|
mock_parse.return_value = 0.5
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["--max-seconds", "1.5"])
|
|
assert result.exit_code == 0
|
|
mock_check.assert_called_once_with(0.5, 1.5)
|