| name | Development |
| description | Implement features using test-driven development methodology. Use when writing new code, implementing features, fixing bugs, or when the user explicitly requests TDD. Follows red-green-refactor cycle with strict discipline. |
| allowed-tools | Read, Write, Edit, Execute, Git |
| dependencies |
Development
Dependencies
None - Core methodology skill that other skills build upon.
Related Skills
- code-reviewer - Complements TDD for comprehensive code quality
- commit-helper - Used after each green state for meaningful commits
Core Rules (Non-Negotiable)
- NEVER write production code without a failing test first
- Write minimum code to pass the test
- Run tests and verify green state before proceeding
- Commit only when all tests pass
- One behaviour per test
The TDD Cycle
🔴 RED → Write failing test
🟢 GREEN → Write minimum code to pass
✅ VERIFY → Run all tests, confirm passing
💾 COMMIT → Save working state
👀 REVIEW → Review the code with the code-reviewer skill
⚠️ Fix issues → fix issues arising from the code review
🔵 REFACTOR → Improve code (optional, keep tests green)
💾 COMMIT → Save refactored state
Step-by-Step Process
Before Starting
- Identify the simplest behaviour to implement next
- Describe the test to the user in plain English
- Confirm approach before writing any code
- Announce:
🔴 RED → Writing failing test for [behaviour]
Step 1: RED - Write Failing Test
Instructions:
- Write ONE test for ONE behaviour
- Use descriptive test name:
test_<function>_<scenario>_<expected_result> - Test the simplest case first (empty, zero, null, single element)
- DO NOT write any production code yet
- Show the test to the user
Example progression:
- First:
test_add_zero_and_zero_returns_zero - Second:
test_add_positive_numbers_returns_sum - Third:
test_add_negative_numbers_returns_sum
Step 2: Verify RED State
- Run the test
- Confirm it fails with expected error:
- Function doesn't exist, OR
- Returns wrong value, OR
- Throws wrong exception
- Show failure output to user
- If test passes without code: Fix the test
- Announce:
✅ Test fails as expected
Step 3: GREEN - Write Minimum Code
Instructions:
- Announce:
🟢 GREEN → Writing minimum code to pass test - Write ONLY enough code to make current test pass
- Hard-coded return values are acceptable initially
- Resist writing "future-proof" code
- Show the code to user
Examples:
Test: assert add(0, 0) == 0
Code: return 0 ✅ Minimum
Test: assert add(1, 2) == 3
Code: return a + b ✅ Now justified
Step 4: Verify GREEN State
- Run ALL tests
- Confirm all pass
- Show test results to user
- If any fail: Fix production code immediately
- DO NOT PROCEED until all tests green
- Announce:
✅ All tests passing
Step 5: Commit
- Create commit message describing the behaviour
- Format:
add [behaviour description] testorimplement [behaviour] - ONLY commit in green state
- Announce:
💾 Committed: [message]
Step 6: Review
- Use the code-reviewer skill to find problems with the implementation.
- Produce a plan to fix issues.
- Fix the issues.
Step 7: Refactor (If Valuable)
When to refactor:
- Code duplication exists
- Code is unclear or overly complex
- Better abstraction is obvious
- Performance improvement needed
If refactoring:
- Announce:
🔵 REFACTOR → [what you're improving] - Make small changes
- Run tests after each change
- If tests fail: Revert immediately
- Show refactored code to user
- Commit with message:
refactor: [description]
If no refactoring needed:
- Announce:
No refactoring needed
Step 8: Choose Next Test
Progressive complexity:
- ✅ Simplest case (empty/zero/null)
- ✅ Simple valid case (one element)
- ✅ Another simple case (different input)
- ✅ Boundary cases (min/max values)
- ✅ Edge cases (special conditions)
- ✅ Error cases (invalid input)
Announce: Next test: [description of next behaviour]
Repeat cycle from Step 1
Test Structure (AAA Pattern)
def test_function_scenario_expected():
# Arrange - set up test data
input_data = create_test_data()
# Act - execute the code
result = function_under_test(input_data)
# Assert - verify result
assert result == expected_value
Common Mistakes to Avoid
❌ Writing Production Code First
- Never write production code before failing test
- Always resist this urge
❌ Writing Multiple Tests at Once
- One test at a time only
- Make it green before writing next test
❌ Writing Too Much Code
- Only write enough to pass current test
- Don't anticipate future tests
❌ Not Running Tests
- Run tests after every change
- Verify green state before proceeding
❌ Skipping Commits
- Commit every green state
- Provides safe revert point
❌ Testing Implementation
- Test behaviour/interface, not implementation
- Tests should survive refactoring
Handling Different Scenarios
New Feature
- Start with simplest acceptance criterion
- Break into small unit tests
- Follow RED-GREEN-REFACTOR for each
- Build complexity gradually
Bug Fix
- Write test reproducing bug (should fail)
- Fix bug (test should pass)
- Commit fix
- Add edge case tests if needed
Refactoring Existing Code
- Add tests for current behaviour first
- Ensure all tests pass
- Refactor with test safety net
- Keep tests green throughout
Communication with User
Always announce:
- Current phase: 🔴 RED, 🟢 GREEN, 🔵 REFACTOR
- What behaviour you're testing
- Test results (pass/fail)
- Commits made
- Next steps
Show to user:
- Each test before running
- Test failure output (RED phase)
- Production code written (GREEN phase)
- Test success output (verification)
- Refactored code (if applicable)
Ask user:
- Confirm approach before starting
- Clarify requirements if ambiguous
- Whether to proceed to next test
Example Interaction
Me: 🔴 RED → Writing failing test for adding zero
[show test code]
Me: Running test...
❌ NameError: name 'add' is not defined
✅ Test fails as expected
Me: 🟢 GREEN → Writing minimum code to pass test
[show production code]
Me: Running all tests...
✅ All 1 tests passing
Me: 💾 Committed: add function returns zero for zero inputs
Me: Next test: adding two positive numbers
[repeat cycle]
Checklist for Each Cycle
- Write failing test (RED)
- Verify test fails for right reason
- Write minimum code (GREEN)
- Run all tests, verify passing
- Commit changes
- Review
- Refactor if valuable (optional)
- Commit refactoring (if done)
- Choose next test
- Repeat
Remember
- Discipline over speed - Follow process even when it feels slow
- Trust the process - TDD prevents bugs and enables fearless refactoring
- Small steps - Each test is a tiny increment
- Always green - Commit frequently in working state
- Let tests drive design - Hard to test = poor design