Test the feature a developer will use

Run real framework components through their public boundary. Make failure, recovery and cleanup part of the test.

On this pageSource-backed Markdown

Start in the consuming app

Use the generated starter’s npm test, npm run check and npm run build. For a smaller app, each service guide supplies a copyable Vitest test and compiler command. These commands run outside the framework repository.

A useful test builds the real App and HTTP factory, makes a request, checks the public response and the persisted result, then closes resources. Do not substitute a mock ActiveRecord for a database test.

Use a disposable database

createGeneratedTestDatabase() creates a unique test-namespaced database and returns its connection plus destroy(). Pass that connection at App boot. Use ActiveRecord.withDb() for a scoped transaction rather than adding optional DB parameters to feature functions.

Framework service labs read DB_* and optional DATABASE_URL; generated starter tests deliberately use separate TEST_DB_* and clear the application URL. Follow the relevant guide’s configuration, not a production shell.

Keep cleanup in finally/test teardown. A killed process may leave artifacts; inspect exact generated names before removing them. No test should create, reshape or drop a live application database.

Control only external dependencies

Keep framework Auth, Queue, Storage and model conversion real. Replace only external HTTP, email delivery, payment or cloud providers with deterministic responses. Use synthetic credentials and assert that invalid authorization never reaches the provider.

A fake provider proves your application behavior, not the provider integration. Separate capped live integration trials from local tests. Do not quietly contact a paid provider from an ordinary test command.

Cover the boundary, not just one success

For each feature cover useful success, invalid input, unauthorized/foreign ownership, a meaningful failure, recovery and cleanup. Assert persisted values or absence of writes, not only the response code.

Avoid sleeps when the contract accepts a clock or fixed evaluation time. Run SQL suites serially when they share an active App or schema fixture. Test concurrent calls explicitly when concurrency is the behavior under review.

Framework contributor commands

These commands require the monorepo, unlike the consumer commands above. Tests live under the owning service’s tests/. The service runner rejects an unknown service name. Release checks must fail for missing required infrastructure rather than silently claiming success.

Framework checkout only
bash
npm run test:service --workspace @platform/app -- storage
npm run check --workspace @platform/app
npm test --workspace @platform/app
npm run framework:package:test
npm run build --workspace @platform/db3

Verify the packed package

Consumer-facing framework changes need both runtime imports and TypeScript checks from an installed tarball. The package gate covers public subpaths and selected runtime contracts; documented scenario trials additionally copy and run the shipped examples.

A green documentation source test proves synchronization and links. It does not prove a new developer can follow the page, so each documentation batch also gets an independent guide-following review.

Name what actually ran

Report tests, infrastructure, artifact identity and skipped cases. Distinguish author tests, independent consumer trials, browser checks, live provider trials and deployed behavior. A test count or documentation page count is not feature coverage.