Skip to content

Comprehensive Testing

Confidence in our code is vital to maintaining a fast, safe deployment cadence. FRAME incorporates testing as part of the development process.

FRAME promotes a test-driven development (TDD) approach, where tests are written before functional code. This helps ensure the code is robust and that tests are well defined.

Our strategy follows the testing pyramid: dense unit tests, a focused integration layer, and a small set of risk-based end-to-end journeys.

SuffixLayerPlacement
*.test.ts / *.test.tsxUnitColocated next to the module
*.spec.tsIntegration / e2eUnder e2e/ or integration/

Do not use *.e2e-spec.ts. Do not put unit tests in *.spec.ts.

They are fast, isolated, and focused on testing pure logic, functions, and components.

  • We use Vitest across the monorepo for high execution speed and predictable configuration. Unit configs include only **/*.test.ts(x).
  • Apps (apps/*) unit-test business logic, solitary Nest use-cases/controllers, Zustand slices, hooks, and critical UI interactions.
  • Packages (packages/*) unit-test utilities, Zod schemas, codecs, config builders, and exported pure APIs.
  • Unit tests must not hit real databases, network, or filesystem — mock at the boundary.

These verify module boundaries and user journeys.

  • NestJS: Vitest + Nest TestingModule + supertest under apps/nest/e2e/**/*.spec.ts (HTTP contracts such as CSRF, health, authz, authenticated CRUD against a test database).
  • Next.js: Playwright under apps/next/e2e/**/*.spec.ts for critical browser journeys. MSW backs HTTP client unit tests (*.test.ts).
  • @frame/astro / docs: Keep Vitest unit/smoke checks and rely on Starlight link validation at build time. No Playwright suite.

Playwright on PRs runs Chromium only; pushes to main run the full browser matrix.

Typelinesbranchesfunctionsstatements
packages50%50%50%50%
apps40%30%30%40%

Thresholds are enforced with vitest --coverage. Coverage includes src/** (scoped per package) so floors reflect product code. Raise thresholds as coverage improves; prefer patch coverage on new lines for PR honesty.

Turborepo runs affected packages on pull requests (test:affected, test-e2e:affected) and the full suite on pushes to main. CI always passes --coverage for unit tests so thresholds fail the job when unmet. Coverage and Playwright reports are uploaded as workflow artifacts.