| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
parent directory.. | ||||
This directory holds the automated tests for HydroModPy. It is split into five release tiers plus focused auxiliary tiers with different purposes, budgets, and selection rules.
tests/ ├── conftest.py # shared scratch root, update-goldens flag, shared fixtures ├── unit/ # one module under test, < 2 s, no real I/O ├── integration/ # cross-module workflows with shared fixtures, < 10 s ├── regression/ # golden-reference tests for full workflows │ ├── fast/ # routine non-regression tier │ ├── extensive/ # deeper end-to-end non-regression tier │ └── reference/ # committed golden JSON files ├── validation/ # scientific benchmarks (analytical, MMS) │ ├── analytical/ │ │ ├── steady/ │ │ └── transient/ │ └── numerical/ ├── e2e/ # subprocess-level command scenarios ├── performance/ # pytest-benchmark storage-wrapper benchmarks ├── contract/ # compatibility contracts across implementations ├── validity_frame/ # experimental observability tooling (not run by CI) └── _helpers/ # pytest-local helpers and shared builders
| Tier | Target budget | Purpose | Selection |
|---|---|---|---|
| unit | ≤ 1 min total, ≤ 2 s per test | One module under test, pure-Python logic, no external binaries, no real I/O outside tmp_path. | pytest tests/unit/ |
| integration | ≤ 10 s per test | Cross-module workflows exercising more than one HydroModPy subpackage via shared fixtures (tmp_workspace, minimal_config, …). No golden files. | pytest tests/integration/ or pytest -m integration |
| regression/fast | ≤ 5 min | Full launcher/pipeline workflows on mini fixtures, compared to committed golden signatures. | pytest tests/regression/fast/ |
| regression/extensive | ≤ 30 min | Deeper end-to-end golden checks with heavier fixtures. | pytest tests/regression/extensive/ |
| validation | ≤ 30 min | Numerical results vs analytical / MMS references with documented tolerances. | pytest tests/validation/ |
Declared in the repository-root pytest.ini:
| Marker | Meaning |
|---|---|
| regression | compares output against a committed reference dataset |
| intercomparison | solver-to-solver regression based on compact comparison metrics |
| validation | compares output against an analytical/numerical reference |
| analytical | validation against a closed-form solution |
| steady | steady-state case |
| transient | transient case |
| fast | cheap tier (fast regression or quick validation) |
| slow | long-running test, skipped from fast CI |
| extensive | deeper regression tier |
| nwt | MODFLOW-NWT / MODPATH / MT3DMS |
| mf6 | MODFLOW 6 / GWT |
| petsc | Linux PETSc Boussinesq runtime |
| integration | cross-module workflow test (auto-applied to tests/integration/) |
| coverage | long-running coverage-focused test |
| solver_sanity | benchmark built directly on the solver SDK (e.g. flopy); validates the external solver against an analytical reference, not the hydromodpy pipeline |
| e2e | end-to-end pipeline scenarios |
| performance | performance baseline benchmarks |
| unit | unit-tier tests, auto-applied by path |
| boussinesq | Boussinesq solver specific test |
| network | requires network access |
| binary | requires a solver binary on PATH |
| gpu | requires a GPU at runtime |
| allow_subprocess | permits subprocess calls inside unit/ |
| timeout | per-test timeout in seconds |
| xdist_group | pytest-xdist worker grouping |
The fast/extensive markers under tests/regression/ are auto-applied based on the file's subdirectory (see tests/conftest.py).
# Unit tests (fastest feedback)
pytest tests/unit/ -q # all unit tests
pytest tests/unit/solver -q # a subpath
pytest tests/unit/ -q -k metrics_nse # keyword filter
# Regression - fast tier (parallel)
pytest tests/regression/fast/ -q -n auto
pytest -m "regression and intercomparison" -q -n 1
# Regression - extensive tier (serial)
pytest tests/regression/extensive/ -q -n 1
# Validation - all analytical cases
pytest tests/validation/ -q
# Marker selection
pytest -m "regression and fast" -q
pytest -m "validation and steady" -q
pytest -m nwt -q
pytest -m "not slow" -q
# Parallel execution (xdist)
pytest tests/unit/ -q -n auto
pytest tests/regression/fast/ -q -n autoThe hmp CLI wraps the most common invocations:
hmp test unit # → pytest tests/unit/
hmp test regression --fast # → pytest tests/regression/fast/
hmp test regression --fast --intercomparison
hmp test regression --extensive
hmp test regression --update-goldensScratch data lands in a repository-external directory to keep the working tree clean:
| Variable | Default | Purpose |
|---|---|---|
| HMP_TEST_SCRATCH_ROOT | /tmp/hydromodpy_tests/ | Shared scratch root; set this to redirect all test artifacts. |
| HMP_COVERAGE | unset | When 1, enables coverage collection during regression runs. |
| PYTEST_DEBUG_TEMPROOT | <scratch>/pytest | Points pytest's tmp_path generator inside the scratch root. |
The conftest sets TMPDIR/TMP/TEMP to a subdirectory of the scratch root so spawned subprocesses inherit the same cleanup policy.
Regression tests compare the output of a pipeline run to a committed signature - a statistical summary of fields stored as JSON under tests/regression/reference/golden_references/{fast,extensive}/.
When a regression assertion fails:
Never edit a JSON file by hand. Use the dedicated CLI switch, which regenerates the golden from the current output:
# Refresh every golden referenced by a test run
pytest tests/regression/ -q -n auto --update-goldens
# Refresh the goldens of a single test module
pytest tests/regression/fast/test_simulation_regression_fast_mf6_regression.py \
-q --update-goldensThen commit the updated JSON files in a dedicated commit. The commit message must state the scientific or code-level reason the signature changed.
Numerical comparisons use numpy.testing.assert_allclose (or equivalent math.isclose) with an explicit rtol/atol. Prefer statistical signatures (min, p25, p50, p75, p95, max, mean, std, sum) over full-array dumps so goldens stay compact and cross-platform stable.
Validation tolerances live in tests/TOLERANCES.md, with some case-local files under validation_cases/**/tolerances.toml when the benchmark owns a named envelope. tests/_helpers/tolerances.py::tol() parses the shared table for tests that need a named tolerance.
The shared fixtures come from tests/conftest.py:
Prefer @pytest.mark.parametrize over copy-pasting N near-identical tests. Keep test files under ~400 LOC: a file that grows beyond that is usually hiding several independent suites.
The active GitHub Actions gates are split across .github/workflows/:
Validation, extensive regression, and e2e are not part of the fast PR-blocking suite; run validation manually before a release with pytest tests/validation/ -q.
| Back | FazBrowse Home | New Git URL |