Skip to content

Instantly share code, notes, and snippets.

@heartshare
Forked from xqliu/tdd-dev.md
Created April 25, 2026 10:34
Show Gist options
  • Select an option

  • Save heartshare/5b01d3fe1a77f98c39eafdf4acf3ebc5 to your computer and use it in GitHub Desktop.

Select an option

Save heartshare/5b01d3fe1a77f98c39eafdf4acf3ebc5 to your computer and use it in GitHub Desktop.
Claude Code TDD Development Skill - Red/Green/Refactor workflow for AI-assisted coding

TDD Development Command

Overview

Test-Driven Development workflow for implementing features with confidence.

Philosophy: Use unit tests to express requirements, then implement to satisfy them.

TDD Cycle (Red-Green-Refactor)

      RED                    GREEN                   REFACTOR
   [Write Test]  ────>  [Make it Pass]  ────>  [Improve Code]
        │                     │                      │
        └─────────────────────┴──────────────────────┘
                          (repeat)

Protocol (Strict Execution)

Phase 1: RED - Express Requirements as Tests

Goal: Write failing tests that describe the desired behavior.

## Requirements Analysis

### Feature Description
[What does this feature do?]

### Acceptance Criteria
1. [Criterion 1]
2. [Criterion 2]
3. [Criterion 3]

### Test Cases
| Input | Expected Output | Edge Case? |
|-------|-----------------|------------|
| X     | Y               | No         |
| Z     | Error           | Yes        |

Test Writing Rules:

  1. Test names describe behavior: Test<Function>_<Scenario>_<Expected>
  2. Use table-driven tests for multiple cases
  3. Cover happy path first, then edge cases
  4. Tests must FAIL initially (proves they test something)
func TestCalculateVitality_NewTask_Returns100(t *testing.T) {
    task := Task{CreatedAt: time.Now()}
    vitality := CalculateVitality(task)
    if vitality != 100 {
        t.Errorf("CalculateVitality() = %d, want 100", vitality)
    }
}

Verification:

go test ./... -run TestNewFeature
# MUST FAIL - if passes, test is wrong

Phase 2: GREEN - Minimal Implementation

Goal: Write the simplest code that makes tests pass.

Rules:

  1. Only write code to pass the current test
  2. No premature optimization
  3. No unnecessary abstractions
  4. Ugly code is OK (we'll fix in refactor)
## Implementation Plan

### Current Test to Satisfy
[Test name]

### Minimal Implementation
[Simplest code that passes]

### Verification
```bash
go test ./... -run TestNewFeature
# MUST PASS

**STOP**: Do not write more code than needed to pass the test!

### Phase 3: REFACTOR - Improve Code Quality

**Goal**: Clean up code while keeping tests green.

**Refactoring Checklist**:
- [ ] Remove duplication (DRY)
- [ ] Improve naming (clarity)
- [ ] Extract methods (single responsibility)
- [ ] Simplify logic (KISS)
- [ ] Remove dead code

**Code Smells to Fix**:
- Long methods (>20 lines)
- Duplicate code
- Magic numbers
- Deep nesting
- Unclear names

**Rules**:
1. Make one change at a time
2. Run tests after EVERY change
3. Revert immediately if tests fail
4. External behavior MUST NOT change

```bash
# After each refactoring step:
go test ./...
# ALL MUST PASS

Phase 4: Repeat

Continue the cycle:

  1. Add next test (RED)
  2. Implement (GREEN)
  3. Refactor (REFACTOR)

Until all acceptance criteria are met.

Complete Example

Scenario: Implement Weekly Streak Achievement

Phase 1: RED

func TestWeeklyStreak_FirstReview_StreakIsOne(t *testing.T) {
    svc := setupTestService(t)
    svc.OnWeeklyReview()
    streak, _ := svc.storage.GetStat("weekly_streak")
    if streak != 1 {
        t.Errorf("streak = %d, want 1", streak)
    }
}
go test -run TestWeeklyStreak
# FAIL: streak = 0, want 1

Phase 2: GREEN

func (s *Service) OnWeeklyReview() {
    s.storage.SetStat("weekly_streak", 1)  // Simplest fix
}
go test -run TestWeeklyStreak
# PASS

Phase 3: REFACTOR

No refactoring needed yet - code is simple.

Phase 1: RED (next case)

func TestWeeklyStreak_ConsecutiveWeeks_Increments(t *testing.T) {
    // ... test consecutive weeks
}

And continue...

Coverage Requirements

  • Core business logic: >90% coverage
  • Check coverage after completing feature:
go test -cover ./internal/...

Anti-Patterns

DO NOT

  • Write implementation before tests
  • Write multiple tests before implementing
  • Skip refactoring phase
  • Commit with failing tests
  • Over-engineer in GREEN phase

RED FLAGS

  • Tests that always pass (not testing anything)
  • Tests that test implementation details
  • Tests without assertions
  • Flaky tests

Trigger Words

Use this command when user says:

  • "TDD"
  • "Test driven"
  • "Write tests first"
  • "Implement with tests"

Remember

"Make it work, make it right, make it fast." - Kent Beck

The order matters:

  1. Work: Tests pass (GREEN)
  2. Right: Clean code (REFACTOR)
  3. Fast: Optimize only when needed

Exit Criteria

Feature is complete when:

  • All acceptance criteria have corresponding tests
  • All tests pass
  • Coverage > 90% for new code
  • Code is clean and well-organized
  • No code smells
  • go build and go test both succeed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment