# 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.