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

141 lines
2.9 KiB
Markdown

---
name: tdd-workflow
description: 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)
```typescript
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**
```typescript
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**
```typescript
class Cart {
items = [];
addItem(item) {
this.items.push(item);
}
}
```
Run test → PASSES
**Step 3: REFACTOR**
```typescript
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 |