Files
fog/docs/adr/0003-mixed-test-runners.md
Maurycy 65af268b86 Add Zod dependency and update API interfaces
- Added Zod as a dependency in package.json.
- Updated pnpm-lock.yaml to include Zod.
- Refactored API interfaces: exported new modules for perk, survivor, mission, and encounter.
- Removed obsolete api-interfaces.ts file.
- Enhanced tests for new schemas in api-interfaces.spec.ts, covering various validation scenarios.
2026-05-07 00:46:03 +00:00

3.2 KiB
Executable File

0003 — Vitest in libs and overlay, Jest in API

  • Status: Accepted
  • Date: 2026-05-06

Context and problem statement

The Nx workspace contains an Angular frontend, a NestJS backend, and three TypeScript libraries. Each subsystem has different test runner support in current Nx generators. Should the workspace standardise on a single runner, accept mixed runners, or prioritise tooling alignment over uniformity?

Decision drivers

  • Generator support. Forcing a non-default runner means working against the grain of the Nx generator and maintaining custom configuration.
  • Speed. Vitest is meaningfully faster than Jest for monorepo work.
  • Ecosystem fit. Angular 21 made Vitest the official default. NestJS examples and community resources still assume Jest.
  • Test isolation. API tests and frontend tests rarely run in the same breath; the cost of a mixed setup is mostly cognitive, not operational.
  • Future migration cost. If we standardise wrong now, the cost of switching later is non-trivial — Jest and Vitest mock semantics differ subtly.

Considered options

  1. Jest everywhere. Use the API's default and force Jest into the libs and overlay.
  2. Vitest everywhere. Force Vitest into the API by manually configuring it after the Nx Nest generator runs.
  3. Mixed: Vitest in libs and overlay, Jest in API. Use each subsystem's native default.
  4. Vitest in shared libs, Jest in both apps. Compromise position.

Decision outcome

Chosen: Mixed — Vitest in libs and overlay, Jest in API.

The Nx Nest generator (@nx/nest:application) only supports jest and none for its unitTestRunner option in the version we're using. The Angular generator (@nx/angular:application) supports vitest-angular (the official Angular Vitest integration) and uses it as the default. The plain JS library generator (@nx/js:library) supports both; we chose Vitest there for consistency with the overlay.

Working with the generator defaults avoids fighting the tooling. The cost — two test runners in one workspace — is small in practice because:

  • Nx's run-many --target=test runs both transparently.
  • Property-based tests (fast-check) work identically in both.
  • Mock semantics differ slightly, but the differences only matter at the test author level, and shared libs use one runner consistently.

Consequences

Positive

  • Each generator runs cleanly with default flags — minimal custom configuration.
  • Vitest gives us fast feedback on the overlay and shared libs (the parts most under iteration).
  • Jest gives us battle-tested Nest testing utilities (Test.createTestingModule, getRepositoryToken, etc.) without translation.
  • When @nx/nest adds first-class Vitest support (likely a future Nx version), migration is contained to one project.

Negative

  • Two sets of test config files (jest.config.cts for API, vitest.config.mts for libs and overlay).
  • Onboarding requires explaining the split.
  • A test utility that targets one runner can't be trivially shared to projects using the other.

Neutral

  • This decision should be revisited when @nx/nest ships native Vitest support, or when the Nest community shifts decisively to Vitest. Track in PROJECT_CONTEXT.md "Open decisions" section.