The canonical developer version of this document lives in the proto-tools repo.
Test Conventions
All tests use flat functions (no test classes). Follow these patterns when writing new tests.Structure
- One-liner module docstring:
"""Tests for {tool/entity name}.""" - No
from __future__ import annotationsin test files - Flat functions only: No
class Test*β use descriptive function names (e.g.,test_blast_search_exact_match) - Section separators: Use
# ββ Section name ββ...for groups. Use# ---------------------------------------------------------------------------+# Integration testsfor the integration boundary - File ordering: Unit tests first, then the integration boundary separator, then integration/GPU tests
- Module-level fixtures: Use
@pytest.fixtureat module level, not inside classes. Usescope="module"for expensive setup - Module-level constants: Deduplicate repeated values as
_PREFIXEDconstants (e.g.,_SETUP_SH,_CRISPR_SEQUENCE) - Test directory naming:
tests/{category}_tests/matchingtools/{category}/
Assertions
- Specific exception matching: Always use
pytest.raises(ExceptionType, match="...")β never barepytest.raises(Exception). For Pydanticge=Nconstraints, match"greater than or equal to N" - No trivial tests: Donβt test that Pydantic stores default values. Test computed properties, validators, normalization, and error cases
tmp_pathovertempfile: Use pytestβs built-intmp_pathfixture
Markers
@pytest.mark.integration: Tests callingToolInstance.dispatch()for CPU tools. Skipped by default; run with--integration@pytest.mark.uses_gpu: Tests callingToolInstance.dispatch()for GPU tools. Auto-skipped when no GPU. Implies environment requirement β do not also add@pytest.mark.integration@pytest.mark.include_in_env_report(category="..."): Add to the primary integration/GPU test for each tool. Category must match the toolβs category- No
@pytest.mark.skip_cifor core dependencies: If a package is inpyproject.toml, its tests should run without special markers @pytest.mark.skip_ci: Only for tests requiring optional/external dependencies not inpyproject.toml
Naming
- Validation tests:
test_{model}_rejects_{what} - Property tests:
test_{model}_{property} - Export tests:
test_export_{format} - Integration tests:
test_{tool}_{scenario}