TDD
Test-driven development cycle: write failing test, implement, refactor
~/.claude/skills/tdd/SKILL.md /tdd TDD Skill
You are a test-driven development expert. When this skill is invoked, implement features using the strict red-green-refactor TDD cycle.
What This Skill Does
Guides development through the TDD cycle: write a failing test first, write the minimum code to make it pass, then refactor. Repeats until the feature is complete.
Step-by-Step Instructions
-
Understand the feature. Before writing any code:
- Clarify what the feature should do
- Identify the acceptance criteria
- Break the feature into small, testable behaviors
- List the behaviors in order from simplest to most complex
-
Set up the test environment. Verify:
- The testing framework is installed and configured
- Tests can be run with a single command
- The test runner supports watch mode for rapid feedback
- Start the test runner in watch mode if available
-
RED: Write a failing test. For the first (simplest) behavior:
- Write ONE test that describes the expected behavior
- Use a clear, descriptive test name:
it("returns 0 for an empty cart") - The test should be specific about expected inputs and outputs
- Run the test. It MUST fail. If it passes, the test is not testing new behavior.
- If the test fails for the wrong reason (import error, syntax error), fix that first.
-
GREEN: Write the minimum code to pass.
- Write the simplest possible code that makes the test pass
- Do not write more code than needed. No “while I’m here” additions.
- Do not optimize. Do not handle edge cases you have not tested yet.
- Run the test. It MUST pass.
- All previous tests must still pass.
-
REFACTOR: Clean up the code.
- Look for duplication, unclear naming, or overly complex logic
- Improve the code structure without changing behavior
- Run all tests after refactoring. They must all still pass.
- Also refactor the tests if they have duplication or unclear structure.
-
Repeat the cycle. Move to the next behavior in your list:
- Write the next failing test
- Make it pass with minimum code
- Refactor
- Continue until all behaviors are implemented
-
Handle the full behavior list. A typical progression:
- Start with the happy path (simplest valid input)
- Add variations of valid inputs
- Add boundary conditions (zero, empty, max)
- Add error cases (invalid input, missing data)
- Add edge cases (concurrent access, special characters)
-
Report the final state.
## TDD Summary
### Feature: [Name]
### Tests Written: N
1. Test name - what it verifies
2. Test name - what it verifies
...
### Implementation
- Files created/modified
- Key design decisions made during refactoring
### Coverage
- All acceptance criteria covered
- Edge cases handled
Example Cycle
Behavior: Calculate total price for a shopping cart
Cycle 1 (RED):
Test: "returns 0 for an empty cart"
Fails: function does not exist yet
Cycle 1 (GREEN):
function calculateTotal(items) { return 0; }
Test passes.
Cycle 2 (RED):
Test: "returns item price for a single item"
Fails: always returns 0
Cycle 2 (GREEN):
function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}
Test passes. Previous test still passes.
Cycle 3 (RED):
Test: "multiplies price by quantity"
Fails: does not account for quantity
Cycle 3 (GREEN):
function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
All tests pass.
Cycle 3 (REFACTOR):
Extract item total calculation into a helper.
All tests still pass.
Guidelines
- Never write production code without a failing test first. This is the core discipline.
- Each test should test exactly one behavior. If a test name has “and” in it, split it.
- The failing test must fail for the RIGHT reason (the behavior is not implemented), not the wrong reason (syntax error, missing import).
- “Minimum code to pass” means literally the minimum. Hardcode return values if that makes the test pass. The next test will force you to generalize.
- Do not skip the refactor step. It is where good design emerges.
- If you get stuck, write a simpler test. The behavior you are trying to test might be too big.
- Keep the cycle fast. Each red-green-refactor should take minutes, not hours.
- If a test is hard to write, the code may need a better interface. Let the test drive the design.
- Keep files under 600 lines. Split test files if they get too long.
Copy this into ~/.claude/skills/tdd/SKILL.md to use it as a slash command in Claude Code.