Skip to content

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.