Testing and Quality
For contributors and reviewers, this page defines required test and quality standards across the monorepo.
Root quality gates
pnpm lint
pnpm typecheck
pnpm test
pnpm build
pnpm check:policies
For a single Turbo command across apps/packages:
pnpm run ci
Monorepo Vitest workspace
Root tests are executed by Vitest workspace config at vitest.workspace.ts.
Each package/app/tool test config is registered as its own Vitest project.
pnpm test
pnpm run test --config vitest.workspace.ts
Package-local tests
Most packages expose:
pnpm --filter <package-name> test
pnpm --filter <package-name> test:unit
pnpm --filter <package-name> test:integration
Parameters
<package-name>: workspace package selector (for example @livon/runtime).
CI scope
The CI workflow runs one root command and delegates orchestration to Turborepo.
CI caching includes PNPM store and local .turbo artifacts.
pnpm run ci
Coding quality baseline
- Functional style only.
- Immutable updates.
- No loop keywords.
- No classes and no
this. - No
anyunless explicitly justified in docs/comments.
Executable documentation rules
Unit tests are treated as executable documentation. They must communicate behavior clearly enough that readers understand the implementation schema without opening source files.
Naming
- Use semantic test names with this pattern:
it('should <do> when <happen>', ...). - Prefer behavior-first phrasing over implementation details where possible.
Structure
- Use one top-level
describe('<api>()')block per tested source file. - Inside it, use
describe('happy')anddescribe('sad')to separate success and failure behavior. - Use
beforeAll,beforeEach,afterEach, andafterAllconsistently for setup and cleanup.
Mocking and isolation
- Unit tests should be fully mocked and atomic per behavior.
- Mock every callable dependency with
vi.fn(). - Mock schema and runtime object properties as explicit mock fields when those properties are part of behavior checks.
- Reuse shared mock instances across tests where practical for speed.
- Reset only per-mock state (
mockClear/mockReset) instead of resetting the full Vitest runtime every test. - Assert call parameters explicitly for every relevant interaction.
- Prefer interface-based mock schemas over
typeof-based schemas when both are feasible.
Mock factory pattern
- Keep reusable mock builders under a dedicated
testing/mocksfolder in package source. - Prefer composable factories where higher-level mocks call lower-level mocks.
- Recommended pattern:
const createBaseSchemaMock = (overrides?: Partial<SchemaWithChain>) => ({
parse: vi.fn(),
typed: vi.fn(),
optional: vi.fn(),
nullable: vi.fn(),
describe: vi.fn(),
refine: vi.fn(),
before: vi.fn(),
after: vi.fn(),
and: vi.fn(),
...overrides,
});
const createStringMock = (override: Partial<StringSchemaMock> = {}) => ({
...createBaseSchemaMock(),
min: vi.fn(),
max: vi.fn(),
email: vi.fn(),
regex: vi.fn(),
...override,
});
Branch coverage requirement
- For every changed file, test all reachable branches with explicit happy/sad cases.
- Missing branch tests are considered incomplete implementation work.
See Governance and Rule Sources and Coding Style Guide for the canonical rule set.