--- description: "Testing conventions: Arrange/Act/Assert structure, naming, mocking strategy, coverage targets, test independence" globs: ["**/*test*", "**/*spec*", "**/*Test*", "**/tests/**", "**/test/**"] --- # Testing - Structure every test with Arrange / Act / Assert section comments using language-appropriate syntax (`# Arrange` for Python, `// Arrange` for C#/Rust/JS/TS) - One assertion per test when practical; name tests descriptively: `MethodName_Scenario_ExpectedResult` - Test boundary conditions, error paths, and happy paths - Use mocks only for external dependencies; prefer real implementations for internal code - Aim for 75%+ coverage on business logic; **90% floor / 100% aim on critical paths** (code paths where a bug would cause data loss, security breaches, financial errors, or system outages — identify from acceptance criteria marked as must-have or from `security_approach.md`). 90% is the enforcement floor (blocking in CI / refactor verification / release pre-flight); 100% is the aspirational aim — drift below 100% but at-or-above 90% is acceptable. Both numbers are canonical — see `cursor-meta.mdc` Quality Thresholds. - Integration tests use real database (Postgres testcontainers or dedicated test DB) - Never use Thread Sleep or fixed delays in tests; use polling or async waits - Keep test data factories/builders for reusable test setup - Tests must be independent: no shared mutable state between tests ## Test environment (this project) - **Unit tests** (`tests/unit/`): may run locally on the dev workstation (`pytest tests/unit/` in the project venv). Local PASS is equivalent to Jetson PASS for this tier because the suite is fully synthetic. - **Blackbox / e2e / performance / resilience / security / resource-limit** tests (`tests/e2e/`, `e2e/tests/`, `tests/perf/`, …): MUST run on the Jetson Orin Nano Super (or a Jetson-equivalent arm64 agent). Use `scripts/run-tests-jetson.sh` for local dev; CI runs `.woodpecker/01-test.yml` on the colocated arm64 Jetson Woodpecker agent. - Do NOT run e2e tests on the local workstation and report the result. If the Jetson is unreachable, the e2e verdict is "not run" — record the gap in `_docs/_process_leftovers/` rather than substituting a local result. - Tests gated by `RUN_REPLAY_E2E` or `@pytest.mark.tier2` are expected to SKIP locally; that is correct behaviour, not a failure to investigate. - Canonical source for this policy: `_docs/02_document/tests/environment.md` § Where each tier runs (active policy).