Skip to content

refactor(test-cases): consolidate diagnostic execution and drift-check integration tests#789

Merged
lewisjared merged 8 commits into
mainfrom
refactor/test-case-execution-consolidation
Jul 6, 2026
Merged

refactor(test-cases): consolidate diagnostic execution and drift-check integration tests#789
lewisjared merged 8 commits into
mainfrom
refactor/test-case-execution-consolidation

Conversation

@lewisjared

@lewisjared lewisjared commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Description

Slims the diagnostic test-case machinery down to a single execution path and turns the provider integration tests into genuine drift checks.

Previously the same execute+build sequence was implemented three ways (Diagnostic.run, the TestCaseRunner mirror, and a bespoke validate_result), and test_run_test_cases only asserted a run succeeded — it never checked the committed bundle for drift. There was also a parked, always-skipped offline validator (RegressionValidator / test_validate_test_case_regression) superseded by the store-backed ref test-cases replay baselines.

Changes:

  • Add a capture_regression hook to Diagnostic.run (keyword-only, defaults to False, so production execution is unchanged). TestCaseRunner.run now delegates to it instead of hand-mirroring execute+build, leaving one execute+build sequence in the codebase.
  • Remove the parked test_validate_test_case_regression tests across all four providers and delete the now-unused RegressionValidator (and its unit tests).
  • Replace validate_result with a shared assert_test_case_no_drift helper. test_run_test_cases now re-executes each test case using the same stage_execute/stage_build/stage_compare stages as ref test-cases run, rebuilds the committed bundle, and compares it to the tracked regression/ baseline within tolerance. This asserts both that the diagnostic still executes and that its committed bundle has not drifted — via re-execution, not replay.
  • Document that ingestion of the committed bundles into the database is covered separately by the executor result-handling tests and is intentionally out of scope for these integration tests.
  • Add scripts/step_test_case.py, a debugging aid to step through the execute or replay of a single test case using the same test-cases CLI stages.

Net: +153 / −552 across the test/execution layers.

Checklist

Please confirm that this pull request has done the following:

  • Tests added
  • Documentation added (where applicable)
  • Changelog item added to changelog/

Summary by CodeRabbit

  • New Features

    • Added generated “no drift” integration tests that re-run diagnostics and compare rebuilt outputs against committed regression baselines.
    • Introduced support for capturing regression output during diagnostic runs to improve validation consistency.
  • Bug Fixes

    • Strengthened test validation so successful execution alone is no longer enough; results must also match the expected baseline.
    • Simplified diagnostic test execution to use a single shared approach across providers.
  • Documentation

    • Updated testing guides and API docs to reflect the new regression-testing workflow and current public surface.

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@lewisjared, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 15 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ad779ad2-e9e6-4e2c-b34c-3795578cf030

📥 Commits

Reviewing files that changed from the base of the PR and between c753b18 and 25f94f8.

📒 Files selected for processing (3)
  • packages/climate-ref-core/tests/unit/test_diagnostics.py
  • packages/climate-ref/src/climate_ref/testing.py
  • packages/climate-ref/tests/unit/test_testing.py
📝 Walkthrough

Walkthrough

This PR removes RegressionValidator from climate_ref_core.testing, adds a keyword-only capture_regression parameter to Diagnostic.run, and introduces assert_test_case_no_drift/create_no_drift_test helpers in climate_ref.testing. Provider integration tests are refactored to use the new factory; the unused run_test_case fixture is removed; documentation and changelog are updated.

Changes

Regression validation replacement

Layer / File(s) Summary
Diagnostic.run capture_regression parameter
packages/climate-ref-core/src/climate_ref_core/diagnostics.py, packages/climate-ref/src/climate_ref/conftest_plugin.py
Diagnostic.run adds a keyword-only capture_regression: bool = False that conditionally calls prepare_regression_output; MockDiagnostic.run and FailedDiagnostic.run are updated to match the new signature.
RegressionValidator removal
packages/climate-ref-core/src/climate_ref_core/testing.py, packages/climate-ref-core/tests/unit/test_testing.py, docs/api-surface.md
The RegressionValidator class, related imports, its API-surface entry, and its dedicated unit test class are removed.
assert_test_case_no_drift and create_no_drift_test
packages/climate-ref/src/climate_ref/testing.py, packages/climate-ref/tests/unit/test_testing.py
validate_result is replaced with assert_test_case_no_drift (executes a diagnostic, rebuilds the committed bundle, compares against the baseline manifest) and create_no_drift_test (a per-provider parameterised pytest factory); TestCaseRunner.run now delegates to diagnostic.run(..., capture_regression=True); unit tests are updated accordingly.
Provider integration test adoption
packages/climate-ref-esmvaltool/..., packages/climate-ref-example/..., packages/climate-ref-ilamb/..., packages/climate-ref-pmp/tests/integration/test_diagnostics.py
Each provider's integration test module removes manual fixtures, parameter collection, and the parked regression test, replacing test_run_test_cases with create_no_drift_test(provider).
Fixture removal
packages/climate-ref/src/climate_ref/conftest_plugin.py
The unused run_test_case fixture and its TestCaseRunner import are removed, along with its documentation entry.
Documentation and changelog updates
docs/how-to-guides/testing-diagnostics.md, changelog/789.trivial.md
The how-to guide adds a Pytest Integration section, custom test guidance, marker examples, and a debugging walkthrough; the changelog documents the consolidation.

Sequence Diagram(s)

sequenceDiagram
  participant Test as Integration Test
  participant Factory as create_no_drift_test
  participant Assert as assert_test_case_no_drift
  participant Diagnostic
  participant Bundle as Committed Bundle
  Factory-->>Test: test_run_test_cases (parameterised)
  Test->>Assert: assert_test_case_no_drift(config, diagnostic, test_case_name, paths, tmp_path)
  Assert->>Diagnostic: run(definition, capture_regression=True)
  Diagnostic-->>Assert: ExecutionResult
  Assert->>Bundle: rebuild committed bundle from outputs
  Assert->>Bundle: compare against regression baseline
  Assert-->>Test: assertion pass/fail on drift
Loading

Possibly related PRs

  • Climate-REF/climate-ref#761: Both PRs modify packages/climate-ref-core/src/climate_ref_core/testing.py's RegressionValidator/regression-validation machinery, with this PR removing it entirely in favour of the new drift-test flow.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the main refactor: consolidating diagnostic execution and adding drift-check integration tests.
Description check ✅ Passed The required sections are present and mostly complete, but the changelog checklist item is left unchecked despite a changelog entry being added.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/test-case-execution-consolidation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
core 92.46% <100.00%> (+0.19%) ⬆️
providers 86.97% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...imate-ref-core/src/climate_ref_core/diagnostics.py 97.36% <100.00%> (+0.03%) ⬆️
...s/climate-ref-core/src/climate_ref_core/testing.py 89.13% <100.00%> (-0.61%) ⬇️
packages/climate-ref/src/climate_ref/testing.py 97.22% <100.00%> (+4.11%) ⬆️

... and 23 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
scripts/step_test_case.py (1)

100-104: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicated catalog-existence check.

The catalog-existence guard is duplicated verbatim (aside from the function name in the error message) between _run_execute and _run_replay. Could be extracted into a small helper, though the benefit is limited given this is a debugging script.

Also applies to: 125-129


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 724a730e-132e-4a26-b3a6-62713e604f76

📥 Commits

Reviewing files that changed from the base of the PR and between 4383375 and 990318f.

📒 Files selected for processing (13)
  • changelog/789.trivial.md
  • docs/api-surface.md
  • packages/climate-ref-core/src/climate_ref_core/diagnostics.py
  • packages/climate-ref-core/src/climate_ref_core/testing.py
  • packages/climate-ref-core/tests/unit/test_testing.py
  • packages/climate-ref-esmvaltool/tests/integration/test_diagnostics.py
  • packages/climate-ref-example/tests/integration/test_diagnostics.py
  • packages/climate-ref-ilamb/tests/integration/test_diagnostics.py
  • packages/climate-ref-pmp/tests/integration/test_diagnostics.py
  • packages/climate-ref/src/climate_ref/conftest_plugin.py
  • packages/climate-ref/src/climate_ref/testing.py
  • packages/climate-ref/tests/unit/test_testing.py
  • scripts/step_test_case.py
💤 Files with no reviewable changes (2)
  • docs/api-surface.md
  • packages/climate-ref-core/tests/unit/test_testing.py

Comment thread scripts/step_test_case.py Outdated
…k integration tests

Collapse the diagnostic execution paths down to a single execute+build
sequence and make the provider integration tests assert the committed
regression bundle has not drifted.

- Add a `capture_regression` hook to `Diagnostic.run` so the regression
  runner reuses the production execute+build sequence instead of mirroring
  it; `TestCaseRunner.run` now delegates to it.
- Remove the parked offline `test_validate_test_case_regression` tests and
  the now-unused `RegressionValidator` (superseded by the store-backed
  `ref test-cases replay` baselines).
- Replace `validate_result` with a shared `assert_test_case_no_drift`
  helper: `test_run_test_cases` re-executes each case and compares the
  rebuilt committed bundle to the tracked baseline within tolerance.
  Bundle ingestion is covered by the executor result-handling tests and is
  documented as out of scope here.
@lewisjared lewisjared force-pushed the refactor/test-case-execution-consolidation branch from 990318f to b3ad98d Compare July 6, 2026 01:33
…oss providers

The four provider integration test modules were byte-identical apart from the provider import.
Each now wires its suite in one line via climate_ref.testing.create_no_drift_test,
which builds the parameterized drift test and resolves test-case paths
with TestCasePaths.from_diagnostic, the same resolution the CLI uses.

Also remove the unused run_test_case pytest fixture;
custom tests should use TestCaseRunner directly.
Replace the removed run_test_case fixture section with the current setup:
the generated per-provider drift test, custom tests via TestCaseRunner,
and a new troubleshooting section on debugging a failing test case
(output slots, baseline diffing, replay vs run, pytest --pdb).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1844c8f6-db39-41a2-ae93-a85fd5761e29

📥 Commits

Reviewing files that changed from the base of the PR and between 990318f and c753b18.

📒 Files selected for processing (13)
  • changelog/789.trivial.md
  • docs/api-surface.md
  • docs/how-to-guides/testing-diagnostics.md
  • packages/climate-ref-core/src/climate_ref_core/diagnostics.py
  • packages/climate-ref-core/src/climate_ref_core/testing.py
  • packages/climate-ref-core/tests/unit/test_testing.py
  • packages/climate-ref-esmvaltool/tests/integration/test_diagnostics.py
  • packages/climate-ref-example/tests/integration/test_diagnostics.py
  • packages/climate-ref-ilamb/tests/integration/test_diagnostics.py
  • packages/climate-ref-pmp/tests/integration/test_diagnostics.py
  • packages/climate-ref/src/climate_ref/conftest_plugin.py
  • packages/climate-ref/src/climate_ref/testing.py
  • packages/climate-ref/tests/unit/test_testing.py
💤 Files with no reviewable changes (2)
  • docs/api-surface.md
  • packages/climate-ref-core/tests/unit/test_testing.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/climate-ref-core/src/climate_ref_core/diagnostics.py
  • packages/climate-ref-core/src/climate_ref_core/testing.py

Comment thread packages/climate-ref/src/climate_ref/testing.py
assert_test_case_no_drift called get_case directly after checking only
for a missing test_data_spec, so an unknown test case name surfaced a
bare StopIteration instead of the friendlier TestCaseNotFoundError that
TestCaseRunner.run already raises for the same situation. Add the
matching has_case guard and document the raised exceptions.
@lewisjared lewisjared merged commit 67f1580 into main Jul 6, 2026
26 checks passed
@lewisjared lewisjared deleted the refactor/test-case-execution-consolidation branch July 6, 2026 03:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant