dev-testing/SKILL.md
MUST USE for testing, QA, regression protection, and release verification — unit, integration, API, contract, Playwright E2E, CI, security-scan, coverage, and TDD strategy. Triggers: write tests, regression test, Playwright, E2E, contract test, coverage, CI flake, TDD, test, testing, QA, 테스트, 회귀 테스트, 품질 게이트.
npx skillsauth add lidge-jun/cli-jaw-skills dev-testingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Balance: ~40% Backend/API, ~40% Frontend/E2E (Playwright), ~20% Cross-cutting (CI, Security, TDD, Coverage) -- directional guidance, not a hard ratio.
Scope: test harnesses, fixtures, mock policy, runners, Playwright, CI gates, coverage. Root-cause analysis and debugging playbooks → dev-debugging.
dev-code-reviewer.dev-devops.dev-data.dev-uiux-design.
This skill activates by change surface when work needs verification depth, regression coverage, or a reproducible test harness.C0/C1 work (small local patches): See
dev§0.0 Work Classifier + §0.1 Patch Fast-Path before reading references.
devis canonical:dev§0.2 Rule Classes, §3 Verification Gate, and §5 Safety Rules apply to all work governed by this skill.
| File | When to Read | What It Covers |
|------|-------------|----------------|
| references/core/crud-test-matrix.md | When choosing verification depth for a classified task, or testing a CRUD slice | Risk-tier minimums, per-operation negatives, UI smoke rule |
| references/edge-first-testing.md | New unit/service/integration tests for features (skip for regression/contract tests) | Edge-first principle, test order by change type, 11-class edge matrix |
| references/backend-testing.md | Backend/API testing | Supertest patterns, DB fixtures, auth mocking |
| references/ci-pipeline.md | CI configuration | GitHub Actions, gates, caching, parallelism |
| references/load-testing.md | Performance/load testing, C3+ production readiness | k6/Locust, test types, measure→profile→verify, CI gates |
| references/ml-evaluation.md | ML model/LLM evaluation, quality gates | LLM-as-judge, RAGAS, DeepEval, CI eval gate, regression detection. CI eval gates are dataset-versioned + regression-based: pin prompts/models/retrieval config, preserve traces, calibrate judges on golden examples, fail only on meaningful regressions or safety failures |
When tests depend on current external API behavior, provider docs, CI service
behavior, test-environment versions, dependency audit evidence, or recorded
mock/fixture sources, read the active search skill and follow its
source-fetch and evidence-status rules.
| Model | Best For | Emphasis | |-------|----------|----------| | Test Pyramid | monoliths, libraries | speed, isolation | | Testing Trophy | modern web apps, REST backends | confidence-to-cost | | Test Honeycomb | microservices, async systems | boundary verification |
| Layer | Default Share | Typical Tools |
|-------|---------------|---------------|
| Static analysis | base layer | tsc, ESLint, mypy, Ruff |
| Unit | ~25% | Vitest, Jest, pytest |
| Integration | ~50% | Supertest, httpx, Testcontainers |
| Contract | ~10% | Pact, OpenAPI validators, Schemathesis |
| E2E | ~10% | Playwright |
| Manual / exploratory | ~5% | human review |
| Problem | Primary Harness | Avoid | |---------|-----------------|-------| | pure business rule | unit / service test | browser test | | route + middleware + serialization | API integration test | mocking the route itself | | DB query / migration / transaction | real DB integration test | fake repository for SQL correctness | | frontend consuming backend JSON | contract test | manual-only verification | | rendered critical flow | Playwright smoke | asserting internal React state | | rendered artifact (visual correctness) | render-grounding loop (dev-pabcd C-RENDER-GROUNDING-01) | static parse / tsc alone |
dev-debugging, then return here for the regression harness.dev §3 DEV-VERIFY-FLOOR-01; CRUD per-operation negative coverage is owned by references/core/crud-test-matrix.md.When the real evaluator is scarce, paid, rate-limited, or opaque and local tests are
proxy metrics for a score/objective, apply §9.5 (single owner of GATE-ORACLE-VALIDITY-01,
GATE-PREFIX-HORIZON-01, GATE-INVARIANT-EV-01, GATE-HOLDOUT-LEAKAGE-01,
GATE-AGREEMENT-STATS-01). Pairs with dev-pabcd §10 Optimization-Loop Meta-Rules.
| Technique | Use for | Default tools | When | |-----------|---------|---------------|------| | Property-based | Pure logic, parsers, serializers, state machines, API invariants | fast-check (TS), Hypothesis (Python) | DEFAULT for invariant-heavy code | | Mutation | Judging test-suite strength on critical domain logic, validators, security branches | Stryker (JS/TS), mutmut (Python) | Selective, after stable unit/property tests — not every PR |
toMatchScreenshot, Playwright trace generation, expect.schemaMatching).Deep reference:
references/backend-testing.md
| Layer | Verify | TypeScript Default | Python Default | |-------|--------|-------------------|----------------| | Service layer | validation, orchestration, domain errors | Vitest | pytest | | API layer | status, envelope, middleware, auth | Supertest | httpx / ASGITransport | | Repository layer | SQL / ORM correctness | Testcontainers + real DB | Testcontainers + real DB | | Background jobs | idempotency, retry, dead-letter | Vitest + fake clock | pytest + monkeypatch |
real deterministic dependency
→ Testcontainers / ephemeral infra
→ recorded responses / thin fake
→ manual stub / fake
→ framework mock as last resort
Mock dependencies at service boundaries. Use Supertest/httpx for route-level integration tests. Match response envelope shape from backend contracts.
Use a real database when verifying migrations, transactions, unique constraints, foreign keys, query translation, and performance-sensitive SQL. Use Testcontainers for real DB truth in correctness-sensitive persistence tests. Start container in beforeAll/fixture setup, capture connection URI.
fixtures/contracts/ or equivalent.Contract tests protect the frontend↔backend boundary. They sit between API tests and browser tests. Rule: Playwright proves the experience. Contract tests prove the shared shape.
success, data, error, metaerror.coderequestId propagation| Style | Best For | Tooling | |-------|----------|---------| | consumer-driven contract | rapidly changing frontend/backend teams | Pact | | schema-first contract | OpenAPI-led backends | OpenAPI validators, Schemathesis | | type-level contract | TS monorepos | shared types / codegen | | full-stack smoke | final user confidence | Playwright |
PactV4 (aliased Pact) is the current interface and supports Pact Specification v4;
treat PactV3 as the legacy spec-v3 API. Workflow:
pacts/ → publish to broker → provider verifiesSee references/backend-testing.md for a full example.
Use schema-based API testing (Schemathesis) to verify OpenAPI/GraphQL contract compliance. (Dredd is legacy/inactive — do not adopt for new projects.)
Use Playwright after API and contract tests are already trustworthy. Browser tests should validate rendered flows, accessibility-critical interactions, and real integration seams that lower layers cannot prove alone. Helper Scripts Available:
scripts/with_server.py - Manages server lifecycle (supports multiple servers)
Run scripts with --help first — treat as black boxes to avoid context window pollution.User task → Static HTML? → Read file → find selectors → write Playwright script
→ Dynamic app? → Server running? → No: `python scripts/with_server.py --help`
→ Yes: Recon-then-action (navigate → screenshot → selectors → act)
# Single server:
python scripts/with_server.py --server "npm run dev" --port 5173 -- python your_automation.py
# Multiple servers:
python scripts/with_server.py \
--server "cd backend && python server.py" --port 3000 \
--server "cd frontend && npm run dev" --port 5173 \
-- python your_automation.py
--help first, invoke directly.sync_playwright() for synchronous scripts; always close the browser.expect(page.get_by_role("button", name="Save")).to_be_visible(), then click() on that locator.get_by_role() with an accessible name. Use get_by_label(), get_by_placeholder(), or get_by_test_id() when role/name cannot express the target.networkidle, hard sleeps, and wait_for_timeout() in tests. Wait on observable app-ready signals, locator actions, or expect() assertions.element_discovery.py - Discovering buttons, links, and inputs on a pagestatic_html_automation.py - Using file:// URLs for local HTMLconsole_logging.py - Capturing console logs during automationBrowser QA loads dev-frontend for rendered implementation context.
Playwright owns deterministic suites; native tools own immediate exploratory proof.
QA-TOOL-LADDER-01: start at 1 and state why when skipping:
browser:control-in-app-browser for built or locally served web UI.chrome:control-chrome for real profile, login, extension, or WAF state.computer-use:computer-use for desktop or GUI-only flows; keep credentials human-supervised.agbrowse only for public-URL response-shape proof, never built-UI driving.
Use inspect -> act -> re-inspect; use screenshots plus view_image when DOM inspection fails.
Evidence names the flow, states, result, and screenshots; promote durable flows to Playwright.Full workflow templates:
references/ci-pipeline.md
quality (lint / typecheck)
→ unit + integration tests
→ contract tests
→ Playwright E2E
→ security scan
→ coverage aggregation + artifacts
Structure CI jobs in dependency chain: quality → backend-tests → contract-tests → e2e
Key configuration:
concurrency.cancel-in-progress: true — avoid wasted runsstrategy.fail-fast: false — for matrix builds--shard=${{ matrix.shard }}/Nnpx playwright install --with-deps chromiumSee references/ci-pipeline.md for full GitHub Actions and GitLab CI templates.
| Dimension | When to Use | |-----------|-------------| | Node / Python version matrix | packages, SDKs, shared libraries | | OS matrix | native modules, CLI behavior | | shard matrix | large suites exceeding CI budget |
npx vitest run --shard=1/4
npx playwright test --shard=1/4 --workers=4
pytest -n auto --dist=loadgroup
| Symptom | First Fix | |---------|-----------| | passes locally, fails in CI | deterministic seeds, containerized deps, explicit waits | | order-dependent failure | reset shared state in fixtures | | green on retry only | remove wall-clock / random assumptions | | screenshot noise | stable CI image, mask dynamic regions | Protocol: detect → quarantine if blocking → assign owner → reinstate after repeated green runs.
When ENFORCE_TDD=true is set in project instructions or explicitly requested, this section becomes mandatory.
| Check | Pass Criteria | |-------|--------------| | Test written before implementation? | test file added / updated before or with code | | Failure observed before fix? | red state was actually executed | | Behavior-focused assertions? | checks outputs, side effects, contracts | | Regression locked in? | failing case is now protected by a persistent test |
Prefer one behavior test → minimal implementation → next behavior. Slice by something a user, caller, or consuming module can observe, not by horizontal layers such as "DB", "API", then "UI". Assert through public interfaces and durable contracts. Retire shallow scaffolding tests when a stronger interface or acceptance test covers the same promise.
| Style | Best For | |-------|----------| | London / mockist | orchestration-heavy boundaries | | Chicago / classicist | domain logic and transforms | | Hybrid | most production code | Default to Hybrid: mock external systems, keep internal collaboration real unless it becomes too slow or unstable.
dev-testing owns the regression harness and enforcement loop.dev-debugging owns root-cause methodology once a failure is mysterious or multi-layered.dev-debugging isolates the cause, come back here to lock it in with tests.When an AI writes and reviews its own code, it carries the same assumptions into both steps. Automated tests break this feedback loop.
| Pattern | Description | Test Strategy | |---------|-------------|---------------| | Sandbox/production mismatch | Fix applied to one code path, not both | Assert same response shape in both modes | | SELECT clause omission | New field in response but missing from DB query | Assert all required fields are present and defined | | Error state leakage | Error set but stale data not cleared | Assert state cleanup on error transitions | | Missing rollback | Optimistic UI update without recovery on failure | Assert state restoration after simulated API error |
Name regression tests with BUG-R{N} convention. Assert all required fields with a loop.
When the project supports a sandbox/mock mode, use it for fast DB-free regression testing:
process.env.SANDBOX_MODE = 'true'Rule: Do not add production defensive code solely to satisfy unrealistic tests. A production guard is allowed only when the invalid state can occur at a real boundary or represents an explicit domain rule.
| Production change smell | Likely test problem | Required action |
|---|---|---|
| Internal if (!x) return added after unit test fails | Test fixture omitted required field | Fix fixture factory or test boundary validation |
| Required field made optional to satisfy test | Test is using invalid domain object | Restore required type and update test data |
| Catch-all added so test passes | Test expects silence instead of failure | Assert typed error or user-visible failure |
| Production default added for impossible state | Test bypassed constructor/parser | Use real constructor/parser in test |
| Private helper exported only for test | Test is coupled to implementation | Test public behavior or move helper to test support |
| Sleep/retry added only for test flake | Test lacks deterministic synchronization | Wait on observable condition or fake clock |
| NODE_ENV === "test" branch added | Test-only production behavior | Remove branch; improve test harness |
Required questions before adding a guard:
Banned patterns: process.env.NODE_ENV === "test" branches, silent fallbacks for impossible internal state, making required types optional for mocks, exporting internals only for tests.
Allowed guards: Boundary validation (process/network/user/file boundary), backward compatibility (documented old schema), security checks, domain invariants, observed production bug regressions, external dependency adapters.
import { axe, toHaveNoViolations } from 'jest-axe'
expect.extend(toHaveNoViolations)
expect(await axe(container)).toHaveNoViolations()
import AxeBuilder from '@axe-core/playwright'
const results = await new AxeBuilder({ page }).analyze()
expect(results.violations).toEqual([])
Verify trace propagation in integration tests. Assert that spans appear for critical paths. Check structured log format matches the schema in dev-backend/references/core/observability.md.
→ Delegated: threat modeling and secure design policy belong to dev-security.
This section covers the automated test hooks and CI gates that enforce those rules.
fast local checks
→ Semgrep / CodeQL gate
→ dependency audit
→ auth / validation regression tests
npm audit --audit-level=high
pip-audit --strict --desc
The returntocorp/semgrep-action wrapper is deprecated (stated by the repo itself) —
run Semgrep natively in CI:
semgrep:
runs-on: ubuntu-latest
container: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- run: semgrep ci --config p/default --config p/javascript --config p/typescript --config p/python
(Open-source alternative engine: Opengrep, the LGPL-2.1 community fork — see
dev-security/references/static-analysis.md.)
Test missing auth (expect 401) and verify error.code matches contract for every auth-protected endpoint.
These are project/risk-based, not universal minimums. Adjust for your context.
| Metric | Suggested Floor | Ideal | |--------|-----------------|-------| | Line coverage | 70% | 85%+ | | Branch coverage | 60% | 80%+ | | Function coverage | 80% | 90%+ | | Diff coverage | 80% | 90%+ |
| Metric | Target | |--------|--------| | Defect detection rate | > 80% | | Mean time to detect | < 1 CI run | | Test signal-to-noise | > 95% | | Contract drift rate | near 0 |
npm test -- --coverage
npx vitest run --coverage
pytest --cov --cov-report=xml
Use these rules when the true evaluator is scarce, paid, rate-limited, or opaque and
local checks are only proxy metrics for a score/objective. PABCD loop response to
repeated candidate deaths is owned by dev-pabcd §10 Optimization-Loop Meta-Rules.
ENFORCE_TDD requirements were followed if enabledrequestId, pagination, and nullability are verified where relevantVerification intensity follows the work class (dev §0.0 / references/core/crud-test-matrix.md):
for C2 UI work, one focused smoke (manual click-through or one Playwright run) plus targeted
checks IS a complete story; for C3/C4 or release-sensitive work, a single smoke is not enough —
run the affected suites and required negatives. Manual/Playwright smoke is a risk-tier rule,
not a universal blocker.
unit / service
→ API integration
→ contract verification
→ Playwright smoke
→ CI gate + coverage + security scan
Source: sol research (SWE-bench containerized evaluation, addyosmani/agent-skills).
An agent that obtains green by weakening tests has not fixed the bug. Before claiming implementation complete:
required (new test for
new behavior), suspicious (deleted assertion, lowered threshold, added skip,
reduced coverage exclusion), or unrelated.Red flags that trigger escalation:
@skip or .skip() added to failing testsas any, @ts-ignore) in test filesWhen TDD is claimed, durable evidence must show:
A TDD claim without RED evidence is not TDD.
tools
Use only on the Codex CLI for native image generation or image editing without an API key. Save final PNG files under ~/.cli-jaw/uploads, report web-ready absolute-path markdown, and send to Telegram or Discord only when explicitly requested.
tools
Ranked repository structure map via `cli-jaw map`. Use for codebase overview, structure map, symbol overview, unfamiliar codebase exploration, architecture orientation. Triggers: repo map, structure map, codebase overview, 와꾸, project structure, unfamiliar code.
tools
cli-jaw Design workspace: create, preview, run, and export design pages from the right sidebar. Covers panel UX, direct-write workflow, artifact lifecycle, wireframe generation, design system, and Open Design adapter.
development
MUST USE for infrastructure and delivery work — container builds, deploy pipelines, Kubernetes, Infrastructure as Code, SRE foundations, edge/serverless, ML infrastructure. Triggers: Dockerfile, K8s manifests, CI/CD pipeline, Terraform/IaC, release/deploy, devops/infra/deploy or release_cd task_tags.