How-to: Run Tests and Check Coverage#
Problem#
You want to run tests and check coverage across all optional dependency sets.
Quick Start#
Single Environment (uv)#
For basic development without the heavier optional plotting stacks:
cd chemparseplot
uv sync --extra test
uv run pytest tests/ --ignore=tests/tutorials
This installs the base test floor used by the main parser and NEB suites. The remaining coverage still needs the heavier optional stacks: jax, pandas, and plotnine.
Full Coverage (pixi)#
pixi manages multiple environments with different optional deps. Each env runs its test subset, then results combine:
pixi run cov
This runs:
Environment |
Deps |
What it tests |
|---|---|---|
test |
ase, polars, scipy, matplotlib |
Core parsers, projection, NEB, trajectory |
plot |
|
Surface fitting, landscape rendering |
chemgp |
|
ChemGP HDF5/JSONL parsers, plotnine plots |
plumed |
|
PLUMED FES parsing and reconstruction |
The cov task cleans stale files, runs all four env tasks, then calls coverage combine and coverage report --fail-under=90.
Individual Environments#
pixi run -e test test-base # base tests only
pixi run -e plot test-plot # with jax + cmcrameri
pixi run -e chemgp test-chemgp # with pandas + plotnine
pixi run -e plumed test-plumed # plumed tests only
Coverage Report#
After any test run:
uv run coverage report --show-missing
Or for HTML:
uv run coverage html
# open htmlcov/index.html
How Coverage Combine Works#
Each pixi env task runs
pytest --covwhich writes.coverageThe task renames it to
.coverage.<env>(e.g..coverage.test)coverage combinemerges all.coverage.*into one.coveragecoverage reportreads the combined file
The [tool.coverage.run] in pyproject.toml has parallel = true and source_pkgs = ["chemparseplot"]. The [tool.coverage.paths] maps different install prefixes back to the source tree.
Writing Tests#
Test Markers#
import pytest
@pytest.mark.neb # needs ase, polars, h5py
@pytest.mark.pure # needs only numpy
Smoke Tests for Plot Functions#
Plot functions are tested by creating a figure, calling the function, and checking axes properties:
import matplotlib
matplotlib.use("Agg") # headless
import matplotlib.pyplot as plt
def test_some_plot():
fig, ax = plt.subplots()
some_plot_function(ax, data)
assert len(ax.lines) > 0
plt.close(fig)
Quality Guidelines#
New modules must have tests in the same PR
Coverage threshold: 90% (enforced by
pixi run cov)Plot functions: at least smoke tests (figure creation + basic assertions)
Parsers: synthetic input data + output schema validation
Keep base-env tests free of the heavier optional stacks (jax, pandas, plotnine)