Skip to content

Commit 6a55e96

Browse files
committed
test: strengthen integration tests and eliminate helper duplication
- Move _make_result/_bench helpers to conftest.py — single source of truth - Add result.assert_outcomes(passed=1) to all 9 integration tests so a broken feature cannot hide behind a passing stdout check - Fix test_no_comparison_with_profile_folder: CODSPEED_PROFILE_FOLDER is an env var, not a CLI flag; use monkeypatch.setenv instead - Ruff TC003/I001 fixes (Path in TYPE_CHECKING block, import sort)
1 parent cc19261 commit 6a55e96

5 files changed

Lines changed: 46 additions & 62 deletions

File tree

tests/conftest.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import importlib.util
4+
import json
45
import os
56
import shutil
67
import sys
@@ -13,6 +14,8 @@
1314
from pytest_codspeed.utils import IS_PYTEST_BENCHMARK_INSTALLED
1415

1516
if TYPE_CHECKING:
17+
from pathlib import Path
18+
1619
from _pytest.pytester import RunResult
1720

1821
pytest_plugins = ["pytester"]
@@ -71,6 +74,28 @@ def ctx_manager():
7174
return ctx_manager
7275

7376

77+
# ---------------------------------------------------------------------------
78+
# Shared test helpers
79+
# ---------------------------------------------------------------------------
80+
81+
82+
def _make_result(tmp_path: Path, filename: str, benchmarks: list) -> Path:
83+
"""Write a minimal CodSpeed result JSON and return its path."""
84+
path = tmp_path / filename
85+
path.write_text(
86+
json.dumps({"instrument": {"type": "walltime"}, "benchmarks": benchmarks})
87+
)
88+
return path
89+
90+
91+
def _bench(uri: str, mean_ns: float, output_hash=None) -> dict:
92+
"""Return a minimal benchmark entry, optionally with an output hash."""
93+
entry: dict = {"uri": uri, "stats": {"mean_ns": mean_ns}}
94+
if output_hash is not None:
95+
entry["output_hash"] = output_hash
96+
return entry
97+
98+
7499
def run_pytest_codspeed_with_mode(
75100
pytester: pytest.Pytester, mode: MeasurementMode, *args, **kwargs
76101
) -> RunResult:

tests/test_comparison.py

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from pathlib import Path
1313

1414
import pytest
15+
from conftest import _bench, _make_result
1516

1617
from pytest_codspeed.comparison import (
1718
BenchmarkDiff,
@@ -21,32 +22,6 @@
2122
print_comparison_report,
2223
)
2324

24-
# ---------------------------------------------------------------------------
25-
# Helpers
26-
# ---------------------------------------------------------------------------
27-
28-
def _make_result(tmp_path: Path, filename: str, benchmarks: list) -> Path:
29-
"""Write a minimal CodSpeed result JSON and return its path."""
30-
path = tmp_path / filename
31-
path.write_text(
32-
json.dumps(
33-
{
34-
"instrument": {"type": "walltime"},
35-
"benchmarks": benchmarks,
36-
}
37-
)
38-
)
39-
return path
40-
41-
42-
def _bench(uri: str, mean_ns: float) -> dict:
43-
"""Return a minimal benchmark entry."""
44-
return {
45-
"uri": uri,
46-
"stats": {"mean_ns": mean_ns},
47-
}
48-
49-
5025
# ---------------------------------------------------------------------------
5126
# find_baseline
5227
# ---------------------------------------------------------------------------

tests/test_comparison_integration.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def test_no_comparison_on_first_run(self, pytester: pytest.Pytester) -> None:
3232

3333
result = run_pytest_codspeed_with_mode(pytester, MeasurementMode.WallTime)
3434

35+
result.assert_outcomes(passed=1)
3536
result.stdout.no_fnmatch_line("*CodSpeed local comparison*")
3637

3738
def test_comparison_appears_on_second_run(self, pytester: pytest.Pytester) -> None:
@@ -44,6 +45,7 @@ def test_comparison_appears_on_second_run(self, pytester: pytest.Pytester) -> No
4445
# Second run — finds the first JSON as baseline
4546
result = run_pytest_codspeed_with_mode(pytester, MeasurementMode.WallTime)
4647

48+
result.assert_outcomes(passed=1)
4749
result.stdout.fnmatch_lines(["*CodSpeed local comparison*"])
4850

4951
def test_comparison_shows_benchmark_count(self, pytester: pytest.Pytester) -> None:
@@ -53,33 +55,31 @@ def test_comparison_shows_benchmark_count(self, pytester: pytest.Pytester) -> No
5355
run_pytest_codspeed_with_mode(pytester, MeasurementMode.WallTime)
5456
result = run_pytest_codspeed_with_mode(pytester, MeasurementMode.WallTime)
5557

56-
# "1 compared" is the footer line produced by print_comparison_report
58+
result.assert_outcomes(passed=1)
5759
result.stdout.fnmatch_lines(["*1 compared*"])
5860

59-
def test_no_comparison_with_profile_folder(self, pytester: pytest.Pytester) -> None:
60-
"""When --codspeed-profile-folder is set, comparison is skipped.
61+
def test_no_comparison_with_profile_folder(
62+
self, pytester: pytest.Pytester, monkeypatch: pytest.MonkeyPatch
63+
) -> None:
64+
"""When CODSPEED_PROFILE_FOLDER is set, comparison is skipped.
6165
62-
The profile folder path is used by the CodSpeed runner in CI; in
66+
The profile folder env var is used by the CodSpeed runner in CI; in
6367
that context the result file is written to a custom location and
6468
the local comparison loop makes no sense.
6569
"""
6670
pytester.makepyfile(_BENCH_FILE)
6771
profile_dir = pytester.path / "profile"
6872
profile_dir.mkdir()
73+
(profile_dir / "results").mkdir()
74+
75+
monkeypatch.setenv("CODSPEED_PROFILE_FOLDER", str(profile_dir))
6976

7077
# First run with profile folder
71-
run_pytest_codspeed_with_mode(
72-
pytester,
73-
MeasurementMode.WallTime,
74-
f"--codspeed-profile-folder={profile_dir}",
75-
)
78+
run_pytest_codspeed_with_mode(pytester, MeasurementMode.WallTime)
7679
# Second run with profile folder — still no comparison
77-
result = run_pytest_codspeed_with_mode(
78-
pytester,
79-
MeasurementMode.WallTime,
80-
f"--codspeed-profile-folder={profile_dir}",
81-
)
80+
result = run_pytest_codspeed_with_mode(pytester, MeasurementMode.WallTime)
8281

82+
result.assert_outcomes(passed=1)
8383
result.stdout.no_fnmatch_line("*CodSpeed local comparison*")
8484

8585
def test_no_comparison_in_simulation_mode(self, pytester: pytest.Pytester) -> None:
@@ -91,4 +91,5 @@ def test_no_comparison_in_simulation_mode(self, pytester: pytest.Pytester) -> No
9191
# Second run in simulation mode — no benchmarks to compare
9292
result = run_pytest_codspeed_with_mode(pytester, MeasurementMode.Simulation)
9393

94+
result.assert_outcomes(passed=1)
9495
result.stdout.no_fnmatch_line("*CodSpeed local comparison*")

tests/test_eval_harness.py

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,14 @@
11
"""Unit tests for pytest_codspeed.eval_harness and output_changed in comparison."""
22

3-
import json
43
import math
54
from pathlib import Path
65

76
import pytest
7+
from conftest import _bench, _make_result
88

99
from pytest_codspeed.comparison import BenchmarkDiff, ComparisonReport, compare_results
1010
from pytest_codspeed.eval_harness import EvalReport, compute_score
1111

12-
13-
# ---------------------------------------------------------------------------
14-
# Helpers
15-
# ---------------------------------------------------------------------------
16-
17-
18-
def _make_result(tmp_path: Path, filename: str, benchmarks: list) -> Path:
19-
path = tmp_path / filename
20-
path.write_text(
21-
json.dumps({"instrument": {"type": "walltime"}, "benchmarks": benchmarks})
22-
)
23-
return path
24-
25-
26-
def _bench(uri: str, mean_ns: float, output_hash=None) -> dict:
27-
entry: dict = {"uri": uri, "stats": {"mean_ns": mean_ns}}
28-
if output_hash is not None:
29-
entry["output_hash"] = output_hash
30-
return entry
31-
32-
3312
# ---------------------------------------------------------------------------
3413
# compute_score
3514
# ---------------------------------------------------------------------------

tests/test_eval_harness_integration.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def test_no_warning_when_output_stable(
3636
pytester, MeasurementMode.WallTime, "--codspeed-capture-output"
3737
)
3838

39+
result.assert_outcomes(passed=1)
3940
result.stdout.no_fnmatch_line("*output changed*")
4041

4142
def test_warning_when_output_changes(
@@ -51,6 +52,7 @@ def test_warning_when_output_changes(
5152
pytester, MeasurementMode.WallTime, "--codspeed-capture-output"
5253
)
5354

55+
result.assert_outcomes(passed=1)
5456
result.stdout.fnmatch_lines(["*output changed*"])
5557

5658
def test_no_warning_without_flag(self, pytester: pytest.Pytester) -> None:
@@ -60,6 +62,7 @@ def test_no_warning_without_flag(self, pytester: pytest.Pytester) -> None:
6062
pytester.makepyfile(_BROKEN_BENCH)
6163
result = run_pytest_codspeed_with_mode(pytester, MeasurementMode.WallTime)
6264

65+
result.assert_outcomes(passed=1)
6366
result.stdout.no_fnmatch_line("*output changed*")
6467

6568
def test_correctness_warning_in_footer(
@@ -75,4 +78,5 @@ def test_correctness_warning_in_footer(
7578
pytester, MeasurementMode.WallTime, "--codspeed-capture-output"
7679
)
7780

81+
result.assert_outcomes(passed=1)
7882
result.stdout.fnmatch_lines(["*1 correctness warning(s)*"])

0 commit comments

Comments
 (0)