Skip to content

Testing

Each test covers product behaviour, a security rule, an HTTP contract, or database behaviour. Its name states what failure it catches, and it runs at the lowest layer that can prove the result.

Layer Use
Unit Parsing, mapping, scoring, state transitions, cache policy, and time boundaries
Ktor route Production authentication, decoding, statuses, headers, safe errors, and rejected-call side effects
PostgreSQL integration Locks, cascades, atomic replacement, concurrent sessions, cleanup, and claim recovery
OpenAPI contract Route inventory, exact schemas, statuses, headers, operation IDs, and security requirements
Frontend adapter Bounded transport, malformed responses, request IDs, and wire-to-model mapping
Component and Storybook Rendering states, validation, focus, keyboard interaction, and accessibility
Browser workflow Navigation, SSR, hydration, responsive workspaces, and cross-tab behaviour
Live integration A+, Mailpit, manual callbacks, archive streaming, and role boundaries

Tests use fixed clocks and deterministic fixture data. PostgreSQL concurrency tests use the real database engine. Browser cases wait for observable state instead of fixed sleeps. Mocks replace external boundaries, not the route, service, component, or reducer under test.

Run the repository gate from the root:

Terminal window
scripts/verify.sh

The release gate also runs:

Terminal window
scripts/smoke-backend-container.sh --no-cache
scripts/smoke-frontend-container.sh --no-cache
(cd frontend && bun audit --prod)
(cd frontend && bun run test:mutation)

bun run test:mutation runs a focused StrykerJS check over the sign-in response parser, bounded HTTP reader, cross-origin request policy, course-configuration validation and merge logic, and grade-publication outcome mapping. The command runner executes the owning unit tests for each mutant and fails below the configured floor. The floor describes only these selected pure decision modules, not the application as a whole. The scheduled and release workflow reports surviving mutations and writes a local JSON report for inspection.

JVM mutation testing is not a build gate. PIT supports Kotlin through the Arcmutate Kotlin plugin, which requires a licence file. That prevents the gate from running from the checked-in project and public dependencies alone. Kotlin security rules use boundary, table-driven, and failure-injection tests instead.

scripts/test-course.sh verify-live checks the deployed boundary of the isolated Comprehensive Test Course. Test the ordinary Compose stack separately; the fixture environment has different configuration and volumes.

Use the official Svelte testing guidance to choose a runner and render mode. Pure model and transformation tests run in the unit project. Components that depend on browser layout, selection, focus, observers, or hydration run in the Playwright-backed browser project. Tests using runes outside a component use a .svelte.test.ts filename so the Svelte compiler applies the same semantics as production code.

Remote-function tests cover input validation, owned result mapping, precise query updates, and service failures. Route tests cover SSR, load parallelism, cookies, redirects, and safe error mapping. The official remote-functions contract defines the browser export as a generated caller whose implementation runs on the server. Tests must exercise the relevant side of that boundary. Mocking the transformed function does not test transport.

quality/test-inventory.md covers Kotlin, Python, frontend, browser, Storybook, documentation, Caddy, container, PostgreSQL, and benchmark verification. A source is accepted only after its assertions and distinct failure modes have an inspected rationale in the corresponding review file. Reviews store a digest of the inspected source or test body, so adding or changing a case invalidates the review. Record one inspected source at a time with node scripts/test-inventory.mjs --write --review-source <path> --review-note "<what was verified>". The command requires fresh evidence and cannot refresh the repository wholesale. bun run test:inventory rejects missing, stale, or unresolved reviews, disabled tests, duplicate stable names, and exact duplicate coverage at the same production boundary.