Skip to main content
Targets: 80% coverage on business logic, 60% overall.

What makes a good test

A test that breaks when you rename a private variable is testing the wrong thing.
Every function that can fail needs at least one test per failure mode. The happy path is the case least likely to regress.
it("returns 403 when caller does not own the resource") — the name is the specification.
Mock the database, the HTTP client, the external service. Never mock an internal helper — that tests the mock.
expect(result).toBeDefined() is nearly useless. expect(result.status).toBe(403) is a test.
Every it() must run in isolation. Never rely on state set up by a previous block.
Inject them as parameters, or use vi.useFakeTimers().

Accessibility assertions

Every new interactive component includes an axe assertion — see Frontend conventions.

Security fixes

Three tests, every time: the attack payload, the 401 boundary, the 403 boundary. See Security conventions.

The regression-test gate

If a PR’s diff touches a service or an API route, the same diff must add or modify at least one test file:
It does not demand a test per file — it demands that logic changes are not shipped with zero new tests. It fails open: if the base ref or diff cannot be resolved, it skips rather than blocking, so it can never become a flaky wall. Two auditable bypasses:
  • [no-test] in the HEAD commit subject or body — for a genuine refactor, config or docs-adjacent change.
  • A path glob in scripts/regression-test-allowlist.json, with a reason.
The gate exists because a PR once claimed a test in its commit message that was never committed. CI proves the code compiles and existing tests pass; nothing else proved a logic change came with a test.

Structural twins

Where two functions must stay in sync by construction — parallel resolvers, an alias map and its consumer, a GET and a POST that share a guard — pin them with a same-shape test, so divergence fails CI instead of surviving until someone notices. The alias lockstep test in src/lib/contracts/variables.test.ts is the reference pattern, and the OpenAPI artifact paths use the same idea.

Tests that pin process

Some of the repository’s own automation is specified in src/lib/pipeline/ with tests next door — the bot-review summary regex, PR readiness, the path classifier. Bash implementations mirror those specs and are kept honest by npm run test:scripts. If you change the automation, change the spec and its test together.