Testing
This monorepo uses Vitest for automated tests. The root npm run test command runs turbo run test, which executes each workspace’s test script.
Tools by app
| Workspace | Runner | Notes |
|---|---|---|
apps/api | Vitest (vitest) | @vitest/coverage-v8 for coverage. environment: "node" in apps/api/vitest.config.ts matches the Fastify runtime. |
apps/web | Vitest (vitest --run in CI-style runs) | Nuxt 4 stack; @nuxt/test-utils, @vue/test-utils, and jsdom are available for component and app-level tests. |
Shared packages/contracts has no dedicated test script today; schemas are exercised indirectly through API and web usage.
API: layout and commands
-
Colocate tests next to the code under
apps/api/src/**, typically in atests/folder (for example.../adapters/http/tests/*.test.ts,.../application/use-cases/tests/*.test.ts). -
Run API tests from the repo root:
npm run test --workspace=apiOr from
apps/api:npm run testThe API
testscript runs Vitest with coverage (vitest run --coverage).
What should be covered
Coverage is a guide, not a score to maximize on every file. Aim for high confidence where behavior and contracts live.
Prefer strong coverage
- Application use cases — orchestration, branching, and mapping between ports and DTOs. These are fast, deterministic unit tests with mocked ports.
- HTTP adapters — handlers and routes: validation (TypeBox / schema failures), status codes, mapping from auth and request context to use-case inputs, and error mapping where applicable.
- Auth and webhook middleware — behavior that depends on headers, plugins, or verification helpers should have focused tests (often with
vi.mock/ stubs).
Acceptable gaps or lower priority
composition.ts(per module) — thin wiring from concrete adapters to use cases. It is excluded from coverage inapps/api/vitest.config.tsbecause dedicated tests rarely add value over integration or route tests that load the real app.- Port interfaces (
*.port.ts) — often contain no executable code; low or zero coverage is normal. - Persistence implementations — Prisma-heavy code may be covered by integration tests (DB or test containers) rather than unit coverage alone; that is a separate decision from Vitest line coverage.
- Bootstrap / infra —
index.ts, loggers, env loading, and similar files may stay partially uncovered unless you add targeted smoke or integration tests.
Web app
Today the web workspace runs a small Vitest suite (for example smoke tests). As you add pages and composables, prefer behavior-focused tests (user-visible outcomes, routing, critical forms) over chasing 100% line coverage on layout-only components.
Coverage reports
With the API test script, Vitest writes an HTML report under apps/api/coverage/ (see reporter in vitest.config.ts) in addition to the terminal summary.