This page documents the test-driven-development skill: its Iron Law, the RED/GREEN/REFACTOR cycle with mandatory verification gates, rationalization patterns to reject, and the companion testing-anti-patterns.md reference. This skill governs how agents write code during plan execution.
For how TDD fits into the broader development pipeline, see the Complete Workflow Pipeline. For applying TDD when authoring new skills (not production code), see Test-Driven Development for Skills. For the debugging counterpart, see systematic-debugging.
| Field | Value |
|---|---|
| File | skills/test-driven-development/SKILL.md |
| Name | test-driven-development |
| Description trigger | Use when implementing any feature or bugfix, before writing implementation code |
| Companion reference | skills/test-driven-development/testing-anti-patterns.md |
skills/test-driven-development/SKILL.md33-45
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
If production code was written before its test exists and was observed failing, the code must be deleted. There are no exceptions:
The three phases form a strict loop. Each phase has a mandatory verification step that must not be skipped.
Diagram: RED/GREEN/REFACTOR Cycle with Verification Gates
Sources: skills/test-driven-development/SKILL.md47-68
skills/test-driven-development/SKILL.md71-112
Write one minimal test that describes the expected behavior. Requirements:
| Requirement | Good | Bad |
|---|---|---|
| One behavior per test | Single expect on one outcome | Test verifies email AND domain AND whitespace |
| Clear name | 'retries failed operations 3 times' | 'retry works' or 'test1' |
| Real code, not mocks | Calls the real function under test | Asserts that a mock was called N times |
Tests should demonstrate the desired API as if writing a usage example. The name should describe behavior, not the mechanism.
skills/test-driven-development/SKILL.md113-129
Run the test suite and confirm three things:
| Outcome | Action |
|---|---|
| Test passes immediately | You are testing existing behavior. Fix the test. |
| Test errors (syntax/import) | Fix the error, re-run. Do not proceed to GREEN. |
| Test fails correctly | Proceed to GREEN. |
skills/test-driven-development/SKILL.md132-166
Write the simplest code that makes the test pass. Do not:
The implementation exists only to pass the current test. Nothing more.
skills/test-driven-development/SKILL.md168-183
Run the full test suite:
Confirm:
| Outcome | Action |
|---|---|
| New test fails | Fix code, not test |
| Other tests fail | Fix regressions before continuing |
| All pass, clean output | Proceed to REFACTOR |
skills/test-driven-development/SKILL.md185-196
Only after GREEN, improve the code's internal quality:
Do not add behavior. After every change, re-run the suite to confirm all tests remain green.
skills/test-driven-development/SKILL.md18-29
| Category | TDD Required |
|---|---|
| New features | Always |
| Bug fixes | Always |
| Refactoring | Always |
| Behavior changes | Always |
| Throwaway prototypes | Ask human partner |
| Generated code | Ask human partner |
| Configuration files | Ask human partner |
The urge to skip TDD "just this once" is a rationalization signal, not a legitimate exception.
skills/test-driven-development/SKILL.md257-270
The skill explicitly catalogs common rationalizations and their rebuttals:
| Rationalization | Reality |
|---|---|
| "Too simple to test" | Simple code breaks. Test takes 30 seconds. |
| "I'll write tests after" | Tests-after pass immediately — proves nothing. |
| "Tests after achieve same goals" | Tests-after answer "what does this do?" Tests-first answer "what should this do?" |
| "Already manually tested" | Ad-hoc ≠ systematic. No record, can't re-run. |
| "Deleting X hours is wasteful" | Sunk cost fallacy. Keeping unverified code is technical debt. |
| "Keep as reference, write tests first" | You'll adapt it. That's testing after. Delete means delete. |
| "Need to explore first" | Fine. Throw away exploration. Start with TDD. |
| "Test is hard = design is unclear" | Listen to the test. Hard to test = hard to use. |
| "TDD will slow me down" | TDD is faster than debugging. Pragmatic = test-first. |
| "Existing code has no tests" | You're improving it. Add tests for existing code. |
skills/test-driven-development/SKILL.md272-288
Any of the following means: Delete the code. Start over.
skills/test-driven-development/SKILL.md291-325
The skill includes a concrete walkthrough for fixing a bug (empty email accepted):
Diagram: Bug Fix TDD Flow
Sources: skills/test-driven-development/SKILL.md291-325
skills/test-driven-development/SKILL.md327-340
Before marking any task complete:
Failure to check all boxes means TDD was skipped. Start over.
skills/test-driven-development/SKILL.md343-350
| Problem | Solution |
|---|---|
| Don't know how to test | Write the wished-for API. Write the assertion first. Ask human partner. |
| Test too complicated | Design is too complicated. Simplify the interface. |
| Must mock everything | Code is too coupled. Use dependency injection. |
| Test setup is huge | Extract helpers. Still complex? Simplify the design. |
Hard-to-test code is a design signal, not a TDD limitation.
skills/test-driven-development/SKILL.md352-355
When a bug is found during development:
Never fix a bug without a test.
skills/test-driven-development/testing-anti-patterns.md1-20
The companion file testing-anti-patterns.md is loaded when writing or changing tests, adding mocks, or considering test-only methods on production classes.
Diagram: Anti-Pattern Reference — Code Entity Map
Sources: skills/test-driven-development/testing-anti-patterns.md1-20 skills/test-driven-development/SKILL.md357-363
skills/test-driven-development/testing-anti-patterns.md275-283
| Anti-Pattern | Fix |
|---|---|
Assert on mock elements (*-mock test IDs) | Test real component or unmock it |
| Test-only methods on production classes | Move cleanup to test-utils/ helpers |
| Mock without understanding side effects | Understand dependency chain first; mock minimally |
| Incomplete mock data structures | Mirror full real API response schema |
| Tests as afterthought | TDD — tests first |
| Over-complex mock setup | Consider integration tests with real components |
skills/test-driven-development/testing-anti-patterns.md14-19
1. NEVER test mock behavior
2. NEVER add test-only methods to production classes
3. NEVER mock without understanding dependencies
Diagram: TDD Skill in the Development Pipeline
Sources: skills/test-driven-development/SKILL.md327-340 skills/test-driven-development/SKILL.md357-363
writing-plans (see Writing Implementation Plans) structures each task with explicit RED/GREEN/REFACTOR steps.subagent-driven-development (see Subagent-Driven Development) dispatches an implementer subagent that is required to follow TDD.systematic-debugging (see systematic-debugging) takes over when a root cause must be investigated; TDD governs how the fix is applied afterward.verification-before-completion (see Other Essential Skills) provides the final gate after the TDD checklist is satisfied.Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.