claude-code-ultimate-guide/examples/skills/tdd-workflow.md
Florian BRUNIAUX b2acc9b115 feat: add Learning Paths, examples, and project governance files
### New Content
- Learning Paths section in README (Junior/Senior/Power User/PM tracks)
- examples/ folder with 18 ready-to-use templates:
  - 4 agents (code-reviewer, test-writer, security-auditor, refactoring)
  - 2 skills (TDD workflow, security checklist)
  - 3 commands (commit, review-pr, generate-tests)
  - 4 hooks (bash + PowerShell for security, formatting)
  - 3 config templates (settings, MCP, gitignore)
  - 2 memory templates (project + personal CLAUDE.md)

### Governance
- CHANGELOG.md: Version history (1.0.0 → 1.1.0 → Unreleased)
- CONTRIBUTING.md: Contribution guidelines for community

### Documentation
- llms.txt: Updated structure with new files/folders

This update makes the guide more actionable with concrete templates
and provides clear learning paths for different skill levels.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-10 14:25:22 +01:00

2.9 KiB

name description
tdd-workflow Test-Driven Development workflow and best practices

TDD Workflow Skill

The TDD Cycle

RED → GREEN → REFACTOR
 ↑__________________|

1. RED: Write a Failing Test

  • Write the smallest test that fails
  • Test should fail for the right reason
  • Ensure the test actually runs

2. GREEN: Make it Pass

  • Write minimal code to pass the test
  • Don't optimize yet
  • It's okay if the code is ugly

3. REFACTOR: Clean Up

  • Improve code structure
  • Remove duplication
  • Keep tests passing

TDD Best Practices

Test Naming Convention

should_[expected behavior]_when_[condition]

Examples:

  • should_return_empty_array_when_no_items
  • should_throw_error_when_invalid_input
  • should_calculate_total_when_items_present

Test Structure (AAA)

it('should calculate discount when coupon applied', () => {
  // Arrange - Set up test data
  const cart = new Cart();
  cart.addItem({ price: 100 });
  const coupon = new Coupon('10OFF', 10);

  // Act - Execute the behavior
  cart.applyCoupon(coupon);

  // Assert - Verify the result
  expect(cart.total).toBe(90);
});

Test Isolation

  • Each test should be independent
  • No shared state between tests
  • Use beforeEach for common setup
  • Clean up in afterEach

TDD Workflow Example

Feature: Add item to cart

Step 1: RED

describe('Cart', () => {
  it('should add item to cart', () => {
    const cart = new Cart();
    cart.addItem({ id: 1, name: 'Book', price: 29.99 });
    expect(cart.items).toHaveLength(1);
  });
});

Run test → FAILS (Cart doesn't exist)

Step 2: GREEN

class Cart {
  items = [];

  addItem(item) {
    this.items.push(item);
  }
}

Run test → PASSES

Step 3: REFACTOR

class Cart {
  private _items: CartItem[] = [];

  get items(): ReadonlyArray<CartItem> {
    return this._items;
  }

  addItem(item: CartItem): void {
    this._items.push(item);
  }
}

Run test → Still PASSES

Next iteration: Calculate total

Repeat the cycle for each new behavior.

When to Use TDD

Good for TDD

  • Business logic
  • Complex algorithms
  • API endpoints
  • State management
  • Utility functions

Less Suitable

  • UI layout (visual testing better)
  • Database migrations
  • External integrations (use integration tests)
  • Exploratory/prototype code

Common TDD Mistakes

  1. Writing too much test - Start with smallest failing test
  2. Writing too much code - Only enough to pass
  3. Skipping refactor - Technical debt accumulates
  4. Testing implementation - Test behavior, not internals
  5. Ignoring failing tests - Fix or delete, never skip

Test Doubles

Type Purpose Example
Stub Return fixed data jest.fn().mockReturnValue(42)
Mock Verify interactions expect(mock).toHaveBeenCalled()
Spy Track calls jest.spyOn(obj, 'method')
Fake Simplified implementation In-memory database