TDD Workflow
One-Liner
Drive feature development with tests that describe behavior — one tracer bullet at a time, never bulk-first.
§ 1 · Core Philosophy
Tests verify behavior through public interfaces, not implementation details. Code can be rewritten entirely; well-written tests should survive that rewrite.
The critical anti-pattern: horizontal slicing. Writing all tests first, then all implementation, produces tests written against imagined behavior — they fail on contact with reality. Don't do it.
The correct pattern: vertical slices (tracer bullets). Write one test → implement the minimum to pass it → repeat. Each cycle uses real learning from the previous one.
§ 2 · Workflow
Phase 1 — Plan
Before writing any code:
- Confirm the public interface (function signatures, HTTP endpoints, component props) with the user
- List prioritized behaviors from most critical to least
- Identify what "done" looks like for each behavior
Gate: Interface agreed. Behavior list approved. No code written yet.
Phase 2 — Tracer Bullet
- Write one test describing the first behavior
- Test must:
- Call a public interface (not internal functions)
- Assert on observable output (not internal state)
- Read like a specification ("given X, when Y, then Z")
- Run the test — confirm it fails for the right reason
- Write the minimal implementation to make it pass
- Run again — confirm green
Gate: Test is green. Test would survive a complete rewrite of the implementation.
Phase 3 — Incremental Loop
Repeat Phase 2 for each behavior in priority order:
for each behavior:
→ write test (public interface, behavior assertion)
→ confirm red (right reason)
→ implement minimum
→ confirm green
→ micro-refactor if obvious duplication
Never write more than one failing test at a time.
Phase 4 — Refactor
After all behaviors are covered:
- Extract duplication into well-named helpers
- Deepen modules: if a function does two conceptually separate things, split it
- Rerun all tests — must stay green
- If a refactor breaks a test, the test was coupled to implementation; fix the test
§ 3 · Test Quality Checklist
Before marking any test done, verify:
| Check | Pass Condition |
|---|---|
| Public interface | Test calls the outward-facing API, not internals |
| Behavior assertion | Asserts what the system does, not how |
| Survives refactor | A complete internal rewrite would leave this test green |
| Reads like spec | A reader unfamiliar with the code can understand the intent |
| One behavior | Each test asserts exactly one behavior |
§ 4 · When to Use This Skill
Use when:
- Adding a new feature to an existing codebase
- Building a module from scratch with known requirements
- Fixing a bug (write a failing test for the bug first)
- Pair-programming with an agent on incremental delivery
Do NOT use when:
- Exploring an unfamiliar codebase (use
zoom-outfirst) - The interface is entirely unknown (use
grill-with-docsfirst to clarify) - Writing tests for existing untested code (use
debug-diagnoseto stabilize first)
§ 5 · Relationship to Other Skills
| Skill | When to reach for it |
|---|---|
zoom-out |
Before starting — map the codebase context |
debug-diagnose |
When a test catches a bug mid-cycle |
architecture-review |
After a feature ships — assess if new code introduced shallow modules |
to-prd |
To convert the behavior list into a tracked issue |