# Test Driven Development

> Use when implementing any feature or bugfix, before writing implementation code

- Skill: `hjewkes/test-driven-development` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add hjewkes/test-driven-development`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hjewkes/test-driven-development/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: hjewkes (https://skillmd.com/u/hjewkes)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/hjewkes/test-driven-development

---


# Test-Driven Development (TDD)

## Overview

Write the test first. Watch it fail. Write minimal code to pass.

**Core principle:** If you didn't watch the test fail, you don't know if it tests the right thing.

**Violating the letter of the rules is violating the spirit of the rules.**

## When to Use

**Always:** New features, bug fixes, refactoring, behavior changes.
**Exceptions (ask your human partner):** Throwaway prototypes, generated code, configuration files.

Thinking "skip TDD just this once"? Stop. That's rationalization.

## The Iron Law

```
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
```

Write code before the test? Delete it. Start over.

**No exceptions:** Don't keep it as "reference". Don't "adapt" it while writing tests. Don't look at it. Delete means delete. Implement fresh from tests. Period.

## Red-Green-Refactor

```dot
digraph tdd_cycle {
    rankdir=LR;
    red [label="RED\nWrite failing test", shape=box, style=filled, fillcolor="#ffcccc"];
    verify_red [label="Verify fails\ncorrectly", shape=diamond];
    green [label="GREEN\nMinimal code", shape=box, style=filled, fillcolor="#ccffcc"];
    verify_green [label="Verify passes\nAll green", shape=diamond];
    refactor [label="REFACTOR\nClean up", shape=box, style=filled, fillcolor="#ccccff"];
    next [label="Next", shape=ellipse];

    red -> verify_red;
    verify_red -> green [label="yes"];
    verify_red -> red [label="wrong\nfailure"];
    green -> verify_green;
    verify_green -> refactor [label="yes"];
    verify_green -> green [label="no"];
    refactor -> verify_green [label="stay\ngreen"];
    verify_green -> next;
    next -> red;
}
```

1. **RED** — Write one minimal failing test. Verify it fails for the right reason.
2. **GREEN** — Write simplest code to pass. No extras.
3. **REFACTOR** — Clean up. Keep tests green. Don't add behavior.
4. **Repeat** — Next failing test for next feature.

For detailed examples (good/bad) and step-by-step instructions, see [references/tdd-detailed-process.md](references/tdd-detailed-process.md).

## Red Flags — STOP and Start Over

- Code before test
- Test after implementation
- Test passes immediately
- Can't explain why test failed
- "I already manually tested it"
- "Tests after achieve the same purpose"
- "Keep as reference" or "adapt existing code"
- "Already spent X hours, deleting is wasteful"
- "TDD is dogmatic, I'm being pragmatic"
- "This is different because..."

**All of these mean: Delete code. Start over with TDD.**

For rationalization counters explaining WHY order matters, see [references/why-order-matters.md](references/why-order-matters.md).
For good tests table, verification checklist, and when-stuck guide, see [references/tdd-guidelines.md](references/tdd-guidelines.md).

## Final Rule

```
Production code -> test exists and failed first
Otherwise -> not TDD
```

No exceptions without your human partner's permission.

