Testing
Table of Contents
- Choose the test owner
- Workspace Vitest
- External-service integration
- Docs checks
- Property-based tests
- Browser / rendering tests
- Governance
- Layering
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.