Skip to content

Commit 9d999b5

Browse files
committed
tests(regression): ensure all functions have google style docstrings
1 parent 2a4383f commit 9d999b5

3 files changed

Lines changed: 99 additions & 3 deletions

File tree

tests/regression/cases.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,48 @@
55

66
@dataclass(frozen=True)
77
class RegressionCase:
8+
"""
9+
Represents a single regression test case.
10+
11+
A regression case corresponds to a specific system and a specific YAML
12+
configuration file, along with its associated baseline file.
13+
14+
Attributes:
15+
system (str): Name of the system (e.g. "dna", "benzene").
16+
config_path (Path): Path to the YAML configuration file defining the scenario.
17+
baseline_path (Path): Path to the expected baseline JSON output.
18+
"""
819
system: str
920
config_path: Path
1021
baseline_path: Path
1122

1223

1324
def repo_root() -> Path:
25+
"""
26+
Return the repository root directory.
27+
28+
Returns:
29+
Path: Absolute path to the repository root.
30+
"""
1431
return Path(__file__).resolve().parents[2]
1532

1633

1734
def discover_cases():
35+
"""
36+
Discover all regression test cases from the configs directory.
37+
38+
Iterates over each system directory under `tests/regression/configs`,
39+
and collects all YAML configuration files. Each configuration file is
40+
paired with a corresponding baseline JSON file.
41+
42+
Returns:
43+
list[pytest.Param]: A list of parametrized pytest cases, each wrapping
44+
a RegressionCase instance.
45+
46+
Notes:
47+
- Cases are automatically marked as slow unless the system is "dna".
48+
- Baseline files are not required to exist at discovery time.
49+
"""
1850
base_dir = Path(__file__).resolve().parent
1951

2052
configs_root = base_dir / "configs"

tests/regression/conftest.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44

55

66
def pytest_addoption(parser: pytest.Parser) -> None:
7+
"""
8+
Register custom command-line options for pytest.
9+
10+
Adds options to control regression test execution, baseline updates,
11+
and debugging output.
12+
13+
Args:
14+
parser (pytest.Parser): Pytest CLI parser.
15+
"""
716
parser.addoption(
817
"--run-slow",
918
action="store_true",
@@ -25,6 +34,12 @@ def pytest_addoption(parser: pytest.Parser) -> None:
2534

2635

2736
def pytest_configure(config: pytest.Config) -> None:
37+
"""
38+
Register custom pytest markers.
39+
40+
Args:
41+
config (pytest.Config): Pytest configuration object.
42+
"""
2843
config.addinivalue_line("markers", "regression: end-to-end regression tests")
2944
config.addinivalue_line("markers", "slow: long-running tests (20-30+ minutes)")
3045

@@ -33,14 +48,19 @@ def pytest_collection_modifyitems(
3348
config: pytest.Config, items: list[pytest.Item]
3449
) -> None:
3550
"""
36-
Regression tests are collected and runnable by default.
51+
Modify collected test items to skip slow tests unless explicitly enabled.
52+
53+
Only tests marked with `@pytest.mark.slow` are skipped when the
54+
`--run-slow` flag is not provided.
3755
38-
Only @pytest.mark.slow tests are skipped unless you pass --run-slow.
56+
Args:
57+
config (pytest.Config): Pytest configuration object.
58+
items (list[pytest.Item]): Collected test items.
3959
"""
4060
if config.getoption("--run-slow"):
4161
return
4262

4363
skip_slow = pytest.mark.skip(reason="Skipped slow test (use --run-slow to run).")
4464
for item in items:
4565
if "slow" in item.keywords:
46-
item.add_marker(skip_slow)
66+
item.add_marker(skip_slow)

tests/regression/test_regression.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@
1212

1313

1414
def _group_index(payload: dict[str, Any]) -> dict[str, dict[str, Any]]:
15+
"""
16+
Extract the grouped structure from a regression output payload.
17+
18+
Args:
19+
payload (dict[str, Any]): The full output payload produced by CodeEntropy.
20+
21+
Returns:
22+
dict[str, dict[str, Any]]: Mapping of group IDs to group data.
23+
24+
Raises:
25+
TypeError: If the 'groups' field is not a dictionary.
26+
"""
1527
groups = payload.get("groups", {})
1628
if not isinstance(groups, dict):
1729
raise TypeError("payload['groups'] must be a dict")
@@ -25,6 +37,21 @@ def _compare_grouped(
2537
rtol: float,
2638
atol: float,
2739
) -> None:
40+
"""
41+
Compare grouped regression outputs against baseline data.
42+
43+
Performs a structured comparison of group components and totals,
44+
using numerical tolerances for floating-point comparisons.
45+
46+
Args:
47+
got_payload (dict[str, Any]): Output generated by the test run.
48+
baseline_payload (dict[str, Any]): Reference baseline output.
49+
rtol (float): Relative tolerance for numeric comparisons.
50+
atol (float): Absolute tolerance for numeric comparisons.
51+
52+
Raises:
53+
AssertionError: If any mismatches are found between outputs and baseline.
54+
"""
2855
got_groups = _group_index(got_payload)
2956
base_groups = _group_index(baseline_payload)
3057

@@ -80,6 +107,23 @@ def _compare_grouped(
80107
def test_regression_matches_baseline(
81108
tmp_path: Path, case, request: pytest.FixtureRequest
82109
) -> None:
110+
"""
111+
Execute a regression test for a single scenario and compare against baseline.
112+
113+
This test:
114+
1. Loads a YAML configuration for a given system/scenario
115+
2. Runs CodeEntropy using that configuration
116+
3. Compares the output payload against a stored baseline JSON
117+
4. Optionally updates the baseline if --update-baselines is set
118+
119+
Args:
120+
tmp_path (Path): Temporary directory provided by pytest.
121+
case (RegressionCase): Parameterized regression case.
122+
request (pytest.FixtureRequest): Pytest request object for accessing CLI options.
123+
124+
Raises:
125+
AssertionError: If the output does not match the baseline or baseline is missing.
126+
"""
83127
system = case.system
84128
config_path = case.config_path
85129
baseline_path = case.baseline_path

0 commit comments

Comments
 (0)