ADR-009 — Testing Strategy
ADR-009 — Testing Strategy
Sección titulada «ADR-009 — Testing Strategy»Draft
Context
Sección titulada «Context»Coveris has two distinct halves: Django owns all business logic, Angular is a thin signal-based client. A unified testing policy is needed to define what gets tested, where, and by whom — preventing redundancy and ensuring every behavior has exactly one owner.
Decision
Sección titulada «Decision»Philosophy. Django is the brain. Angular is the screen. If the brain fails, the screen is irrelevant.
- Backend: Exhaustive. Every endpoint has a contract test. Every domain rule has a model test. Every bug leaves a regression guard.
- Frontend: Test signal integration and enforce structural rules. Do not test DOM depth or PrimeNG rendering.
- Contract tests: Every API.md endpoint has a test verifying status codes and response field shapes. A verifier (
test_contract_coverage.py) fails if any endpoint lacks one ([[adr-005-a-contract-testing-pipeline|ADR-005-a]]).
Five Test Layers.
| Layer | Stack | Owns |
|---|---|---|
| Domain / Model | Backend | FSM, computations, constraints, rules engine |
| Component / Service | Frontend | Signal graph, HTTP integration, guards, interceptors |
| Contract | Backend | API.md compliance: status codes + response shapes |
| Architectural guards | Both | Forbidden imports, forbidden patterns, route naming, API.md completeness |
| Regression guards | Both | Prevent recurrence of specific bugs |
Anti-Redundancy Rule. A behavior is tested in exactly one layer. The backend contract test owns “the endpoint returns employee_number as a string”; the frontend service test owns “the service maps it to the component signal”. Neither re-tests the other’s concern.
Test the boundary you own.
Regression Guards. Every bug fixed must leave a preventing test (red → green → permanent). Each has a traceability comment:
# REG: Backlog #42 — employee filter by status returned all statusesLocation: cross-cutting → tests/test_regression_backlog.py; app-specific → apps/<app>/tests/test_regressions.py.
What We Do Not Test.
| Excluded | Reason |
|---|---|
| Framework internals (SimpleJWT, Django ORM, CORS, PrimeNG, Angular CD) | Tested by framework. Sub-ADRs document exceptions. |
| Snapshot tests | Fragile, high maintenance, low value |
| Coverage percentage as KPI | Good tests > a number |
Sub-decisions
Sección titulada «Sub-decisions»- [[adr-009-a-frontend-testing-strategy|ADR-009-a]] — Frontend testing: three layers, signal testing rules, design system enforcement, mock discipline.
- [[adr-009-b-backend-testing-strategy|ADR-009-b]] — Backend testing: three layers, contract test rules, fixture topology, markers, security audit exceptions.
- [[adr-009-c-ci-integration|ADR-009-c]] — CI integration (deferred).
- [[adr-009-d-bdd-e2e-testing|ADR-009-d]] — BDD + E2E with Gherkin + Playwright (deferred).
Operational details (code examples, run commands, rollout plans, gap lists) live in [[testing|docs/dev/testing.md]].
Consequences
Sección titulada «Consequences»- (+) Each behavior has exactly one test in exactly one layer.
- (+) Regression guards grow the safety net with every bug.
- (+) Contract tests keep API.md honest — drift is caught automatically.
- (-) Five layers require understanding where each test belongs.
- (-) Contract tests for 58 endpoints is a significant upfront investment.