Jarvis Docs
Development

Testing Patterns

Conventions and patterns for testing Nous-OSS

Testing Patterns

This document describes the testing conventions used across Nous-OSS. All phases follow these patterns.

Test Tiers

Tests are organized by purpose:

Tier 1 — Contract Tests (Critical)

Does the implementation fulfill the interface contract?

  • Write for every class that implements a shared interface
  • Validate every method required by the contract

Tier 2 — Behavior Tests (Important)

Does the system do what the user expects?

  • Write for every behavioral feature
  • Covers merge semantics, error handling, persistence, isolation boundaries

Tier 3 — Edge Case and Regression Tests (As Needed)

Invalid input, failure conditions, boundary conditions.

  • Write when the SDS identifies specific failure modes
  • Write when bugs are found
  • Write when the implementation handles potentially dangerous input

File Organization

self/<layer>/<package>/
  src/
    __tests__/
      <module-name>.test.ts
    <module-name>.ts
    index.ts
  • Tests live in src/__tests__/ — colocated with the source
  • Test file names match the source module: sqlite-document-store.tssqlite-document-store.test.ts
  • Web app rendered tests may live in package-root __tests__/ when they exercise app routes or client composition rather than a single src/ module.
  • Use .test.tsx for rendered UI suites.

Naming Conventions

Test names: <method or behavior> <expected outcome>

  • Good: get() returns null for non-existent document
  • Bad: test storage, it works

What NOT to Test

  • Type existence — The compiler handles this
  • Pure mocks with no real code — If everything is mocked, nothing is tested
  • Coverage padding — Every test should validate meaningful behavior

Coverage Target

Aim for 80% coverage on behavioral code. Exclude type definitions, stub implementations, generated code, and configuration scaffolding.

Framework

  • Vitest — Unit and integration tests
  • Playwright — E2E tests for web UI (Phase 2+)

Workspace Test Execution

  • Root workspace tests should run via pnpm test from repository root.
  • Root test execution uses vitest.config.mts with explicit test.projects entries so package-local Vitest configs (aliases, include/exclude patterns) apply consistently.
  • For package-only runs, use pnpm --filter <package-name> test.
  • Avoid ad-hoc root vitest run invocations that bypass the intended workspace configuration.

Rendered Web Tests

  • In @nous/web, server-side suites continue to run in the default node environment.
  • Rendered UI suites opt into jsdom per file with a header comment: // @vitest-environment jsdom.
  • Prefer this per-file opt-in when only a subset of a package needs DOM APIs; it keeps non-rendered suites fast and avoids changing the environment for unrelated tests.

Reference

For the full SOP, see .skills/engineer-workflow-sop/implementation-agent/testing-patterns.md.

On this page