Skip to content
Back to skills

Test Design

ASecurity

Judgment for writing and reviewing test code: what to test at which level, how to keep tests trustworthy, and how to audit an existing suite. Trigger: load when writing test code, reviewing a test suite, or deciding what automated coverage a feature needs.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 13, 2026
ai-agentsrustgotesting

Security analysis

A100/100

Scanned October 13, 2026

npx -y skills add jrodrigopuca/local-agents --skill test-design --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Test Design?

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

Security grade badge for Test Design
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jrodrigopuca-test-design/badge)](https://www.skillsdirectory.com/skills/jrodrigopuca-test-design)

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: test-design
description: >
  Judgment for writing and reviewing test code: what to test at which level,
  how to keep tests trustworthy, and how to audit an existing suite. Trigger:
  load when writing test code, reviewing a test suite, or deciding what
  automated coverage a feature needs.
license: Apache-2.0
metadata:
  author: jrodrigopuca
  version: "1.1"
---

## Critical Patterns

### 1. Test at the lowest level that can catch the bug

The pyramid is an economics argument, not a dogma: unit tests are cheap,
fast, and precise; E2E tests are expensive, slow, and vague about causes. Push
each check DOWN: pure logic → unit; component contracts and DB queries →
integration; and E2E only for the few journeys where the money is (login,
checkout, the core loop) — testing through the UI what a unit test could catch
is paying E2E prices for unit information. Inverted pyramids (everything E2E)
fail slowly, flake often, and explain nothing.

### 2. Test behavior at the contract, not implementation guts

A test that breaks when the code is refactored (behavior unchanged) is
friction; a test that survives a bug is dead weight. Aim at the CONTRACT:
given these inputs/state, this output/effect. Don't assert internal call
sequences or private state — mock at boundaries you don't own (network, clock,
randomness), keep real code running everywhere else. The question for every
test: "if this fails, does it mean a USER-visible promise broke?"

### 3. Every test tells one story: arrange, act, assert

One behavior per test, named as the behavior ("rejects expired coupon at
checkout", not "test3"). Failure output must diagnose without a debugger:
assert specific values, not just truthiness. Shared fixtures for the boring
setup, but the MEANINGFUL data visible in the test itself — a test whose
critical input hides in a factory five files away can't be read as a story.

### 4. Deterministic, or quarantined with an owner — the flakiness rule

A test that fails sometimes is worse than no test: it trains the team to
retry-until-green, which buries real failures. Flakiness causes are almost
always: real time (`sleep`, timeouts) → use fake clocks and explicit waits on
conditions; shared state between tests → isolate per test; network to real
services → stub the boundary; ordering assumptions → make each test
self-contained. Quarantine a flaky test the day it flakes, with an owner and
a date, and fix it that week — a quarantine that lasts a quarter is a
graveyard. Delete it only when the behaviour it guards is covered elsewhere:
a deleted test on a critical path is a coverage hole that shows up green. And
a check that is stochastic by nature — a model's output, a latency — is not
flaky: assert a threshold over N samples, never a single run.

### 5. Coverage guides, contracts decide

Line coverage finds UNtested code (useful); it never proves tested code is
well-tested (a test with no meaningful asserts covers 100% and checks
nothing). Audit a suite by asking: are the RISKS covered — the boundaries from
[flow-hunting](../flow-hunting/SKILL.md), the state collisions, the auth cuts?
Ten tests on the tricky boundary beat a hundred on getters. Never chase a
coverage number for its own sake; it optimizes exactly the wrong behavior.

### 6. Work inside the dev's conventions — you're a guest in the suite

Test code is code: it follows the repo's existing patterns, naming, helpers,
and framework idioms (read the neighboring tests first, per the senior-dev's
"read before write"). If the suite's conventions are actively harmful (shared
mutable fixtures, sleeps everywhere), don't silently fork your own style —
raise it with the dev as a finding, agree the pattern, then apply it. For
framework specifics, load a `playwright` / `pytest` skill if the host exposes one.

## Resources

- Sibling skills: [flow-hunting](../flow-hunting/SKILL.md) (the paths worth
  automating), [bug-reporting](../bug-reporting/SKILL.md) (every confirmed bug
  ends as a regression test here)
- The dev's testing philosophy this composes with:
  [senior-dev](../../../senior-dev/AGENTS.md), Developer Judgment #5 (tests
  as a safety net, not a ceremony — the numbered list under that heading, not
  the Peer Contract's)

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.