Testing

Table of Contents

Choose the test owner

Run the narrow package command first, then widen when you change shared behavior, cross-module contracts, or user workflows. Each suite has an explicit owner:

Scope Command What it owns
Changed paths pnpm test:select -- --path <path> Prints the narrow commands selected for one or more changed paths. Add --run to execute them.
Workspace JavaScript pnpm test Root-owned Vitest projects, with Switchboard API isolated from the parallel workspace wave.
Web browser and rendering pnpm test:e2e The apps/web Playwright suite.
Native Rust pnpm native:rust:test Non-desktop Rust crate owners.
Desktop Rust pnpm desktop:rust:test Workspace Web and Goobits Desktop Rust owners.

The current root and package scripts are generated in Operational Reference.

Workspace Vitest

pnpm test runs root-owned workspace projects. Nested Git packages are skipped by default and should use their package-local commands when changed. Set GOOBITS_TEST_RUN_NESTED_PACKAGES=1 only when a deliberate nested-package sweep is needed.

The root runner defaults to four concurrent workspace jobs. On a heavily loaded machine, set GOOBITS_TEST_WORKSPACE_CONCURRENCY=1 for a serial run.

External-service integration

Default package tests stay self-contained. Required-service suites fail fast when their connection variable is missing:

VALKEY_URL=redis://127.0.0.1:6379 pnpm --filter @goobits/switchboard test:valkey
DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/auth_test pnpm --filter @goobits/auth test:postgres

CI provisions disposable Valkey and PostgreSQL services and runs both commands. The ordinary Switchboard suite skips Valkey-backed cases without VALKEY_URL; Auth integration tests use pg-mem unless the PostgreSQL owner is selected.

Docs checks

Use Contributing for authored-doc verification policy. Use the route smoke when the change can affect /docs, route generation, docs-engine imports, hydration, or branch-host routing.

Property-based tests

pnpm test:pbt        # fast-check seeded run (FC_SEED=4242, 60 runs)
pnpm test:pbt:heavy  # heavier run (200 runs)

Browser / rendering tests

WGPU and browser renderer tests run through Playwright. Rendering work uses a software-backed ANGLE/SwiftShader path in CI; the maintained browser WGPU renderer uses wgpu's GL/WebGL2 backend, not the browser WebGPU API. Probe behavior live after shader changes rather than trusting cached expectations. Package-specific browser suites keep their own Playwright configuration and lifecycle owner.

Governance

Run pnpm check:test-governance after moving or adding tests. It enforces test placement, BDD structure, and the test-title behavior lexicon implemented by scripts/quality/lintBddLexicon.ts. That test-writing vocabulary is separate from the product and architecture glossary.

Layering

  • Unit (Vitest): pure logic, domain rules, formations, adapters.
  • Integration (Vitest or a required-service owner): package boundaries, persistence, and protocol behavior without a browser.
  • E2E (Playwright): user-visible behavior, interaction parity, rendering, and browser API contracts.
  • Keep tests with the package that owns the behavior, even when another app is the first consumer.
  • Keep external dependencies explicit. Default skips are reserved for clearly named opt-in scenarios, not missing infrastructure.
  • Prefer the lightest check that proves the change; widen for shared surfaces.