test-driven-development
Write tests before implementation code. Use when starting new features or fixing bugs. Covers Red-Green-Refactor cycle and TDD best practices.
When & Why to Use This Skill
This Claude skill facilitates the Test-Driven Development (TDD) methodology, guiding developers through the essential Red-Green-Refactor cycle. It prioritizes code quality and reliability by ensuring tests are written before implementation, leading to better software design, reduced technical debt, and a robust safety net for future refactoring.
Use Cases
- New Feature Implementation: Use TDD to define expected behavior through tests before writing any production code, ensuring clear requirements and cleaner architecture.
- Bug Resolution: Reproduce reported bugs by writing a failing test case first, then implementing the fix to ensure the issue is permanently resolved and won't regress.
- Complex Business Logic: Apply the Red-Green-Refactor cycle to break down complicated logic into small, verifiable steps, maintaining high confidence in code correctness.
- API Contract Development: Define and validate API endpoints and data structures through automated tests to ensure consistent behavior across different services.
- Code Refactoring: Leverage the existing test suite as a safety net to fearlessly clean up and optimize code while ensuring all functionality remains intact.
| name | test-driven-development |
|---|---|
| description | Write tests before implementation code. Use when starting new features or fixing bugs. Covers Red-Green-Refactor cycle and TDD best practices. |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep |
Test-Driven Development
The TDD Cycle
- Red: Write a failing test
- Green: Write minimal code to pass
- Refactor: Improve code while keeping tests green
Workflows
- Write Test: Write a test that describes desired behavior
- Run Test: Verify it fails (Red)
- Implement: Write minimal code to pass
- Run Test: Verify it passes (Green)
- Refactor: Clean up while tests stay green
- Repeat: Next test case
TDD Example
Step 1: Red - Write Failing Test
describe("Calculator", () => {
test("adds two numbers", () => {
const calc = new Calculator();
expect(calc.add(2, 3)).toBe(5);
});
});
// Run: FAIL - Calculator is not defined
Step 2: Green - Minimal Implementation
class Calculator {
add(a: number, b: number): number {
return a + b;
}
}
// Run: PASS
Step 3: Refactor (if needed)
Code is already clean, move to next test.
Step 4: Next Test
test("subtracts two numbers", () => {
const calc = new Calculator();
expect(calc.subtract(5, 3)).toBe(2);
});
// Run: FAIL - subtract is not defined
TDD Benefits
- Design Feedback: Tests reveal design issues early
- Documentation: Tests document expected behavior
- Confidence: Refactor fearlessly with test safety net
- Focus: One behavior at a time
TDD Tips
- Start Simple: Begin with the simplest test case
- One Assert: Each test should verify one behavior
- Descriptive Names: Test names are documentation
- No Logic in Tests: Tests should be obvious
- Fast Feedback: Tests should run in milliseconds
When to Use TDD
- New features with clear requirements
- Bug fixes (write failing test first)
- Complex business logic
- API contract development
When TDD is Less Useful
- Exploratory/prototype code
- UI layout changes
- Simple CRUD operations