ABI Testing Guide¶
Test counts and coverage move with the code, so use the latest CI run for current numbers. This page explains where tests belong, which commands are useful locally, and what CI requires.
Test layout¶
Layer |
Location |
Purpose |
External tools |
|---|---|---|---|
Unit |
|
Core logic, schemas, parsers, contracts, runtimes |
No |
Integration |
|
CLI/core boundaries, dry-runs, golden traces |
Normally no |
Smoke |
|
Real tools and value-level workflow checks |
Usually yes |
SciPlot |
|
Schema, renderer, lint, CLI/API, Unicode layout |
Report dependencies |
Name files test_<feature>.py and functions test_<behavior>. Every behavior change should come
with a regression test. Tests that run external tools use @pytest.mark.smoke,
@pytest.mark.requires_tools, or both.
Local commands¶
# Main suite
pytest tests/ -v --tb=short
# CI-like suite without external tools
pytest tests/ src/abi/sciplot/tests/ -v --tb=short \
--strict-markers -m "not requires_tools"
# Focused module
pytest tests/unit/test_dag_planner.py -q
# Real-tool tests only
pytest tests/ -v -m requires_tools
# Branch-aware global gate
pytest tests/ src/abi/sciplot/tests/ \
--strict-markers -m "not requires_tools" \
--cov=src/abi --cov-branch --cov-report=term \
--cov-report=json:coverage.json --cov-fail-under=75
python scripts/check_module_coverage.py --coverage coverage.json
The CI floor is 75% plus risk-based per-module line/branch gates. Do not put a fixed measured percentage or test count in maintained guidance.
Plugin contract gates¶
Every built-in plugin must:
satisfy the Python plugin protocol checked by
assert_plugin_contract;load its registry and standard-table schemas;
have a declarative
pipeline_dag.yaml;provide a contract for every external-tool output, or a justified explicit exemption;
ship a non-empty
limitations.yaml.
Run strict lint for all built-ins:
for plugin in \
amplicon_16s easymetagenome metagenomic_plasmid metatranscriptomics \
rnaseq_expression viral_viwrap wgs_bacteria
do
abi contract-lint --type "$plugin" --strict
done
python scripts/audit_contract_coverage.py
Strict lint turns warnings into failures and also enforces missing/invalid/empty limitations declarations and output-contract coverage.
Golden traces¶
Golden traces are stored at the repository root:
golden_traces/
├── amplicon_16s.jsonl
├── metagenomic_plasmid.jsonl
├── metatranscriptomics.jsonl
├── rnaseq_expression.jsonl
└── wgs_bacteria.jsonl
They currently cover five workflow families, not all seven built-ins. Replay them with:
pytest tests/integration/test_golden_traces.py -q
When a deliberate plan change modifies a trace, review the semantic diff before updating the fixture. Do not regenerate traces merely to make a test pass.
Smoke and benchmark tests¶
tests/smoke/test_*_benchmark.py contains real-tool checks for the original five
workflow families, and abi.testing.benchmark provides a generic
expected_assertions.yaml evaluator. The current repository checkout does not
ship a complete data/benchmarks/ fixture tree. Before running those tests,
verify that the required dataset, expected assertions, tools, databases, and
environment variables are provisioned. CI excludes requires_tools tests from
the default quality gate.
EasyMetagenome and ViWrap are covered by contract, dry-run, integration, and release wheel smoke paths, but do not currently have the same checked-in value-level benchmark fixture shape as the original five.
CI and release surface¶
The repository intentionally keeps four workflows:
ci.yml: Python 3.10–3.13 lint/format/mypy, tests, 3.12 coverage, strict contract lint, docs, Compose validation, package build, wheel smoke, and a migration gate;docker.yml: manual-only builds and smoke tests for the selected plugin or all plugins; an explicitpushenables registry publication with provenance/SBOM, and published images are multi-platform except RNA-seq;release.yml: reusable CI gate, build, Twine check, clean-wheel smoke, and GitHub Release creation;publish-pypi.yml: download the exact GitHub Release artifacts and publish with PyPI Trusted Publishing.
For CI/Docker/build-input changes run:
pytest tests/unit/test_docker_configuration.py -q
docker compose -f docker/docker-compose.yml config --quiet
python -m build
For documentation changes run:
bash docs/build_docs.sh
Before review¶
Python changes require Ruff, formatting, mypy, focused pytest, and affected integration tests. Plugin changes additionally require strict contract lint, dry-run validation, and relevant smoke tests. Release changes have additional gates; Docker changes have configuration checks and a recommended manual image build described in the development workflow and release guide.
Record commands and results in the pull request. If a real-tool, container, or cluster check cannot run, state that explicitly and describe the remaining risk.