Testing
Testing pyramid, frameworks (Vitest, Playwright, bats), mocking rules, Live Smoke-Test Gate for raw SQL. Use when writing or reviewing tests.
Overview
Testing is a reference skill loaded by developers and reviewers when writing or reviewing tests. It defines the testing pyramid, recommended frameworks per layer, and strict mocking rules that prevent tests from becoming brittle or misleading.
Testing Pyramid
- Unit Tests (70%) — test individual functions and classes in isolation. Mock all external dependencies. These form the foundation and provide the fastest feedback loop.
- Integration Tests (20%) — test interaction between modules, services, and databases. Verify that components work together correctly. Use real database connections where feasible.
- E2E Tests (10%) — test critical user flows end-to-end. These are the most expensive to write and maintain, so focus on the highest-value paths.
Recommended Frameworks
- Backend — Jest, Mocha or Vitest
- Frontend — Vitest with React Testing Library for component tests
- E2E — Playwright (preferred) or Cypress for browser automation
Mocking Rules
- Mock external APIs (Stripe, AWS, third-party services) — never hit real services in tests
- Mock database calls in unit tests — use real databases only in integration tests
- Use dependency injection to make mocking easier and more explicit
- Never mock the thing you are actually testing — if the bug class lives in the real integration (wrong client, schema or dialect), a mocked test passes while production fails
- Adapter-path fixture — a mapper spec drives a raw DB-row fixture through the real mapper, never a hand-built output object
- For exact authorization, execution, revision or consumption proofs, assert direct proof equality and add missing/wrong-proof controls through the actual runner
Advanced Testing Gates
- Live Smoke-Test Gate — mandatory for raw SQL, cross-datasource code, migrations, and queue/webhook code. Mocks cannot catch wrong-client queries that compile clean but hit the wrong database at runtime. Run the query against the real target datasource and record the result.
- Live Docker Smoke Test — mandatory for cross-container HTTP/RPC calls, volume-mounted configs, and filesystem paths inside containers. 241 unit tests can pass while 3 independent runtime bugs hide in exec bits, hostnames, and SSL config.
- Silent-Failure Detection — for subprocesses that exit 0 on error (LLM CLIs, cloud tools). Parse structured output instead of checking exit code. Raise errors inside the wrapper, not downstream.
- Spec-Lint Tests — regex assertions over markdown prose contracts in
commands/*.md. Guards against silent regression of command specifications. - Shell Script Testing (bats-core) — red-green discipline for bash scripts (installer, sync, deploy). Isolation via
BATS_TEST_TMPDIR+ HOME redirection. Fixture-builder pattern, SUCCESS-marker pattern, sanity-guard tests for destructive flags. - Post-Deploy Smoke Gate — when deployment changes the runtime user, run one full cycle as the new user before switching cron/systemd. Verify external tool auth paths and file I/O permissions.
- Delivery-path fidelity — packaging, installation, upgrade and rollback smoke evidence must come from the real delivery path.
- TDD discipline — RED-GREEN-REFACTOR with a failing test before production code, loaded from its own fragment.
- Legacy failure triage — three buckets for an inherited red suite: stale-delete, fixable-patch, rephrase-the-content.
- Concurrency patterns — provider fan-out and shared-resource acquire/release; custody fixes pair safety regressions with owner-progress tests.
The entry skill routes to one supporting fragment per sub-problem (live-smoke-gates.md, silent-failure-detection.md, bats-and-spec-lint.md, tdd-discipline.md, triaging-legacy-failures.md, concurrency-patterns.md) so agents load only the gate they need.
When It's Used
Loaded during /dr-do when writing code (TDD cycle: write test, implement, refactor) and during /dr-qa when reviewing test coverage and quality. A reference skill with no model — inherits from the calling agent.