Skip to content
Back to skills

Testing Policy

ASecurity

Canonical FFS testing doctrine — mock-minimization ladder, real-browser verification, console/network tripwires, independent test authorship, BDD-as-executable-input, coverage floor, smoke design. Other skills reference this instead of restating it.

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 26, 2026
testingpythonbashsqltestingapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 26, 2026

npx -y skills add austinmao/feature-fix-swarm --skill testing-policy --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Testing Policy?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Testing Policy
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/austinmao-testing-policy/badge)](https://www.skillsdirectory.com/skills/austinmao-testing-policy)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: testing-policy
description: "Canonical FFS testing doctrine — mock-minimization ladder, real-browser verification, console/network tripwires, independent test authorship, BDD-as-executable-input, coverage floor, smoke design. Other skills reference this instead of restating it."
version: "1.1.0"
allowed-tools:
  - Read
  - Bash
  - Grep
  - Glob
---

# testing-policy — one home for how FFS tests

## Host dispatch contract

- Codex: `$skill`, Codex collaboration roles, and GPT-5.6 tiers.
- Claude: `/skill`, Agent/Skill tools, and Claude aliases.
- A bare `/skill` in this shared source denotes the Claude form; Codex dispatches the same named skill as `$skill`.

## When to invoke

- Referenced by `/feature-spec`, `/spec-decompose`, `/feature-implement`, `/code-uplift`,
  `/fix` when writing or judging tests. Load it before authoring any test plan.
- Directly: "what's our testing policy", "how should this be mocked", "what does the
  browser gate require".

## Why this exists

The recurring failure is *green tests, broken browser*: manual testing keeps catching
issues automated tests should have caught. Root causes, in observed order: over-mocked
modules whose fake shapes drift from reality; jsdom silently dropping layout/CSS/
navigation; no real-browser gate in the agent loop; the agent that wrote the code also
grading it. Every rule below exists to close one of those.

## 1. Mock-minimization ladder (stop at the first rung that holds)

1. **Real thing.** Real DB (testcontainers / local Postgres / SQLite where the dialect
   allows), real filesystem in a tmpdir, real clock unless the test is about time.
2. **Own adapter over anything you don't own.** Third-party API/SDK → wrap in a thin
   adapter; tests mock YOUR adapter interface; a separate contract test exercises the
   adapter against the real service (or its sandbox) — "don't mock what you don't own".
3. **Network boundary only (MSW-style).** When HTTP must be faked, intercept at the
   network layer so the entire client stack (fetch wrapper, query cache, serialization)
   runs real. NEVER mock your own modules (`vi.mock('./api')` on first-party code is a
   policy violation — that fake shape is exactly what drifts).
4. **jsdom is for logic, not UI truth.** Component/integration tests that assert
   layout, visibility, hover/focus, navigation, or CSS run in a real browser
   (Playwright component tests / e2e). jsdom-only suites may not claim UI coverage.

## 2. Real-browser gate (fail-closed)

Any diff touching web surfaces must pass `scripts/gsd/canary-gate.sh` before ship:
a headless Canary session over the affected flows, gated mechanically on
`results.json`: `status=="passed"` AND `consoleErrors==0` AND `networkFailures==0`,
with staleness check against HEAD. No canary results on a web-touch diff = FAIL.
Zero console errors / zero failed network requests are the cheapest tripwires that
catch most "obviously broken" states — never waive them to make a run green.
Evidence ledger: `python3 lib/runtime_proof.py verify <bundle>` where a spec carries browser-proof
success criteria. Coverage second opinion: `scripts/gsd/qa-coverage-adversary.sh`
(cross-vendor, advisory) lists user-facing flows the QA session missed.

## 3. Independent test authorship

The agent that implemented a change does not author its acceptance/verification
tests. In gsd runs this is structural (executor vs nyquist-auditor vs verifier are
separate spawns) — keep it that way: never collapse test-writing into the executor's
plan "for speed". Same-author tests validate what the code *does*, not what it *should*.

## 4. BDD — executable input, not ceremony

Given/When/Then scenarios are written at spec time (`/feature-spec`) for user-facing
stories ONLY, and they earn their keep by being consumed: each scenario maps to a
Canary step (or Playwright e2e spec) at QA time. No Gherkin for internal/library code
nobody non-technical will read. Scenario names should be greppable from spec.md to the
step scripts that execute them.

## 5. Coverage floor + smoke

- Coverage floor **80%** (unit+integration, per repo rule); measure with the repo's
  real runner (`vitest run --coverage`, `pytest --cov`); never assert coverage from a
  narrowed test selection.
- Post-deploy smoke (≤60s): health endpoint + ONE real critical path (login or the
  product's money path) + the console/network tripwires. `/canary` runs it post-ship.

## 6. Test failures

Fix the implementation, not the test — unless the test asserts a stale contract, in
which case say so out loud in the commit body. Flake protocol: run alone, re-run the
group, clean tree, then name it flake or regression with the reason.

## Anti-patterns (reject in review)

- First-party module mocks (`vi.mock`/`jest.mock`/`monkeypatch` on own code) where a
  boundary intercept works.
- UI assertions in jsdom claiming browser truth.
- Tests asserting mock-call counts instead of observable behavior.
- Coverage runs scoped to the changed files only, presented as suite coverage.
- Sleeping/timeout-based e2e waits where a deterministic wait exists.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.