# Tests
This guide defines language-neutral testing expectations and patterns.
For Python-specific commands and examples, see the
[Python testing guide](tests-python.md).
## 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:
```text
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.md` and 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
1. During development, run the fastest relevant tests continuously.
2. Before commit, run language-specific quality checks and targeted test suites.
3. 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:
1. Reassess interface boundaries and dependency injection points.
2. Replace implicit dependencies with explicit constructor/function parameters.
3. Reduce fixture complexity and isolate the failing scenario.
4. Prefer small, composable tests over broad multi-concern tests.
5. Capture the rationale for unavoidable compromises in `tests/README.md`.
## Language-Specific Overlays
- [Python testing guide](tests-python.md) - Python-specific test patterns and
commands.