Add property-based, contract, regression, and plotting tests - #536
Merged
Conversation
Fills the gaps identified in the testing-strategy review: Hypothesis-driven invariant tests for the core factorization/OPQ primitives, explicit error-path tests for documented AnnData-key/parameter contracts, a golden regression fixture pinning pf2() output on fixed synthetic data, and smoke tests for the previously ~0-30%-covered plotting modules. Adds hypothesis as a dev dependency and a shared synthetic-data conftest, and gates CI on 85% coverage (currently 89%) via tool.coverage.report.fail_under. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the testing strategy discussed for this repo: raises
scrisecoverage from 74% to 89% and adds test categories the suite was missing entirely.test_invariants.py, Hypothesis): fuzzes shapes/ranks/seeds to check mathematical invariants that must hold for any valid input — sign-canonicalization idempotence, energy-ordering as a true permutation, self-matching identity inmatch_components_across_ranks, OPQ fidelity non-decreasing in sub-quantizer count, andcorrect_conditions' invariance to uniform rescaling of the condition factors (derived from OLS's scale-equivariance).test_contracts.py): pins the exact exceptions raised when documented AnnData-key/parameter contracts are violated (missingcondition_unique_idxs, missingPf2_*factors, invalidbicvfractions, infeasible rank,X.X is None), so these become loud failures instead of confusing downstream crashes.test_golden_regression.py): pinspf2()'s R2X, component weights, and top-gene-per-component on a fixed synthetic fixture + seed, to catch silent behavior drift from e.g. aparafac2dependency bump.test_plotting_{factors,general,pacmap,stability}.py): the plotting subpackage was at 14–30% coverage; now 70–100%. Checks functions run without raising across edge cases (rank=1, missing pivot columns, 3-gene input) and that the right data lands on the right axis (plot_r2x,plot_bicv_r2x,plot_condition_factorslegends, FMS invariance to component permutation).hypothesisas a dev dependency, a sharedconftest.pysynthetic-data factory (replacing ad hoc per-file fixtures going forward), and a[tool.coverage.report] fail_under = 85gate so coverage regressions are caught in CI automatically.Test plan
uv run pytest --cov=scrise --cov-report=term-missing— 81 passed, 2 skipped, 89% coverage, fail-under gate passesuv run ruff check scrise/uv run ruff format --check scriseuv run ty check scrise🤖 Generated with Claude Code