Testing patterns
Package tests are service-level integration tests. They call public service functions directly and use fixtures to create and remove database state. They are not browser or DOM tests.
Keep tests with the module
packages/@acme/warehousing/
modules/
stock/
server/
tests/
stock.fixtures.ts
stock.spec.tsKeep fixtures close to the module unless several modules genuinely share them. Test public service functions rather than repositories or HTTP handlers:
// packages/@acme/warehousing/modules/stock/tests/stock.spec.ts
import { expect, test } from "./stock.fixtures";
import {
activateStock,
createStock,
deactivateStock,
patchStock,
} from "../server";The package repository must provide and configure the test runner used by the suite. This may be a repository-level development dependency and script shared by its packages, or package-local configuration when the package is developed and tested independently. Test-only tooling must not be declared as a runtime dependency. The reference test files below use Playwright's test API for database integration tests. The Voyzu runtime does not provide Playwright, so a repository that runs these files must install and configure it explicitly.
Test exposed behavior
Every meaningful service operation exposed through UI or API must have a corresponding service test. Cover list, get, create, replace, patch, state transitions, delete, search, filtering, reports, and batch operations when the module provides them.
Assert the returned DTO and the important persisted outcome:
Test full replacement and partial patch separately when both are supported. Test single and batch functions separately. A failed atomic batch must leave no earlier item changed.
Test unhappy paths
Cover the important failure modes:
missing or malformed input;
duplicate business codes;
missing referenced records;
inactive dependencies;
invalid state transitions;
deletion of records that are in use;
protected-field changes after dependent activity exists; and
batch rollback.
Assert both the error and the absence of an invalid side effect:
Use fixtures
Fixtures own test data. They create valid prerequisites, issue unique business codes, track created records, and clean them up after the test.
Cleanup in finally is mandatory. Teardown must be idempotent, remove records in reverse dependency order, remove test audit events where required, and restore any shared reference data the test changed.
Use unique, recognizable codes for every test and worker. Tests must not depend on execution order or data left behind by another run.
Keep service entry points Node-safe
Tests and package scripts may execute outside Next.js. Their service entry point must not transitively load SSR pages that import server-only.
Import SSR pages directly from the page entry point in module.ts; do not re-export them from the Node-safe service barrel.
Checklist
Keep tests below the owning module.
Call public services, not repositories or HTTP handlers.
Cover successful behavior and important business-rule failures.
Assert persisted outcomes and rejected side effects.
Use unique fixture data and make teardown idempotent.
Leave no business, relationship, or audit fingerprint.
Last updated