Skip to content

Testing

Matrix tests fall into five categories. Each one tests a different thing, runs in a different environment, and has a different cost.

Pages in this section

PageWhat it tests
Unit testsOne actor's handlers in isolation, in-process, no external dependencies.
Contract testsAn actor against its static accepts/emits declarations — schema fidelity, op admittance, $introspect shape.
Runtime smoke testsA real Host process under the test harness (createDaemonHarness is the historical name; the harness boots a real Host Service today), verifying install/start/healthcheck.
Package proof testsEnd-to-end "the package does what its README says" tests — typically scripts under scripts/prove-*.ts.
Browser testsUI components in a real browser via Playwright, against a --serve Host.

Where tests live

projects/matrix-3/
├── tests/                              ← cross-package integration tests
│   ├── unit/                           ← unit tests for src/
│   ├── integration/                    ← real-NATS / real-host tests
│   ├── runtime/
│   ├── security/
│   └── supervision/
└── packages/<name>/
    └── tests/                          ← package-local unit tests

The split is by ownership: a test that exercises a single package goes inside that package's tests/. A test that crosses package boundaries (multiple actors, real bus, real gateway) goes under projects/matrix-3/tests/.

Running tests

Per the project root CLAUDE.md § "Build and run":

bash
pnpm install
pnpm test:affected               # tests for packages affected by your changes

Per-package:

bash
pnpm --filter <package-name> test

For a single file (uses tsx + node:test):

bash
cd projects/matrix-3
pnpm exec tsx --test tests/unit/core/MatrixActor.spec.ts

The shared runner is projects/matrix-3/scripts/test.ts. It supports filters by package directory and timeout flags.

What you should run when

StageRun
Inner-loop, edits to one filepnpm exec tsx --test <file>
Done with a coherent changepnpm --filter <package> test
About to commitpnpm test:affected
Before tagging a release / merging to masterthe local pre-merge gate (scripts/ci/premerge-local.sh)

Tip: Real-Host integration tests (Idiom 4 in Actor testing) are slow. Don't run them on every save — let your inner loop be the package-local unit tests.

Test discipline

Three project-level rules apply to every Matrix test:

  • No any, even in tests. Type narrowing is the test-author's responsibility.
  • No "skip" without a ledger entry. Skipping a test silently is forbidden — record the reason and the unblock condition.
  • No deleting tests. If a test is misplaced, move it; don't delete. If the behaviour it tests is gone, the test goes too, but cite the architectural reason in the commit.

Full rules are in the project root CLAUDE.md § "Branch-discipline rules".

See also

Source: projects/matrix-3/packages/test-utils/src/index.ts (test fixtures), projects/matrix-3/scripts/test.ts (runner), projects/matrix-3/tests/ and projects/matrix-3/packages/*/tests/ (real specs).