Tests¶
This guide defines language-neutral testing expectations and patterns. For Python-specific commands and examples, see the Python testing guide.
Core Testing Principles¶
Test observable behavior, not implementation details.
Prefer dependency injection and explicit interfaces over global state mutation.
Keep tests deterministic and isolated from external mutable systems.
Design tests to run quickly in normal development loops.
Target comprehensive line and branch coverage where practical.
Anti-Patterns to Avoid¶
Testing against live external services: Use test doubles for network, cloud, and other remote dependencies.
Over-mocking internal logic: Excessive mocking can hide real integration and contract failures.
Hidden global coupling: Tests should not rely on implicit ordering, process-global state, or residue from previous tests.
Broad exception suppression: Avoid swallowing failures in tests. Keep assertions specific and explicit.
Test Organization¶
Use a predictable test layout with clear ownership and purpose:
tests/
├── README.md # Project-specific conventions and numbering notes
├── data/ # Fixtures, snapshots, mock payloads
├── unit/ # Fast unit tests around public contracts
├── integration/ # Multi-component and boundary tests
└── smoke/ # High-value, end-to-end sanity checks
Recommendations:
Group tests by public capability rather than private source structure where possible.
Keep naming stable and descriptive.
If your project uses numbered test naming, document the numbering scheme in
tests/README.mdand keep it current.
Test Data and Fixtures¶
Store reusable fixtures under
tests/data/with topic-based subdirectories.Prefer minimal fixtures scoped to the test purpose.
Keep snapshot and artifact fixtures reviewable and intentionally versioned.
Use generated data for high-cardinality cases when static fixtures become difficult to maintain.
Validation Workflow¶
During development, run the fastest relevant tests continuously.
Before commit, run language-specific quality checks and targeted test suites.
Before pull request, run the comprehensive project validation suite.
Use stack-specific overlays for command wrappers and tooling conventions.
Coverage Strategy¶
Treat coverage as a quality signal, not a substitute for thoughtful test design.
Cover normal behavior, error behavior, and boundary behavior.
Use exclusion pragmas only as a last resort and document why they are needed.
Troubleshooting Approach¶
When tests are hard to write or unstable:
Reassess interface boundaries and dependency injection points.
Replace implicit dependencies with explicit constructor/function parameters.
Reduce fixture complexity and isolate the failing scenario.
Prefer small, composable tests over broad multi-concern tests.
Capture the rationale for unavoidable compromises in
tests/README.md.
Language-Specific Overlays¶
Python testing guide - Python-specific test patterns and commands.