Testing & CI¶
Test suite¶
345 test functions across 20 files.
uv run pytest # full suite
uv run pytest -n auto # parallel via pytest-xdist
uv run pytest tests/test_graph.py -v
uv run pytest -k "federated" # by keyword
Configuration in pyproject.toml:
[tool.pytest.ini_options]
pythonpath = ["src/fed_maxfuse", "src/cli", "src/shared"]
testpaths = ["tests"]
addopts = "-p no:warnings"
Coverage by area¶
| Test file | Covers |
|---|---|
test_pre_processor.py |
Preprocessing pipeline |
test_graph.py |
k-NN graph construction, Leiden clustering |
test_matching_utils.py |
Matching helpers |
test_correlation.py |
Pearson correlation |
test_federated_params.py |
Federated parameter parsing |
test_distributed_params.py |
Distributed parameter parsing |
test_global_refinement_loop_params.py |
Refinement-loop configuration |
test_evaluation_cluster.py |
Cluster metrics |
test_zadu_abbreviations.py |
Metric name mapping |
test_anndata_loader.py |
AnnData ingestion |
test_cli_generate_utils.py, test_cli_utils.py |
Configuration generation |
test_data_utils.py, test_deep_dict.py, test_verbosity.py |
Utilities |
Supporting libraries: parameterized (table-driven cases), pyfakefs (filesystem isolation
without touching disk), psutil (resource checks), pytest-xdist (parallelism).
Testing is a differentiator here
The upstream MaxFuse reference implementation ships no tests at all. Its two long-standing latent defects survived a rename and a repackaging precisely because nothing checked behaviour. A test suite is the cheapest protection against that, and it is worth maintaining as this codebase evolves.
Linting and static analysis¶
Four tools are configured:
uv run ruff check src tests # lint
uv run ruff format src tests # format
uv run pylint src # deeper static analysis
uv run mypy src # type checking
pyproject.toml configures [tool.ruff] (with lint.pydocstyle, lint.pylint, lint.mccabe,
lint.flake8-tidy-imports), [tool.pylint.*], [tool.mypy], [tool.black], and [tool.isort].
Continuous integration¶
No CI is currently configured
There are no workflow definitions in the repository. Tests, linting, and type checking must be run manually before committing.
A minimal workflow would be a worthwhile addition:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
- run: uv sync --group dev
- run: uv run ruff check src tests
- run: uv run mypy src
- run: uv run pytest -n auto
Before committing¶
uv run ruff format src tests
uv run ruff check src tests
uv run mypy src
uv run pytest -n auto
Testing numerical code¶
Two practices worth following in this codebase specifically:
Seed anything stochastic. Leiden clustering, k-NN construction, and CCA noise initialisation
are all random by default. A test that does not fix seeds will be flaky. Set leiden_seed and
nn_graph_seed explicitly in test configurations.
Test invariants, not just values. Exact floating-point equality is brittle across platforms.
Prefer assertions on properties that must hold: matrix shapes, index ranges, monotonicity,
symmetry, normalisation (unit norms, row sums), and tolerance-based comparisons via
np.testing.assert_allclose.