Test-Driven Development Skill
Enforces strict TDD workflow: write failing tests first, implement minimal code to pass, then refactor. Prevents writing implementation before tests exist, ensuring every line of code is driven by a test case.
Description
This skill implements strict Test-Driven Development (TDD). It enforces the Red-Green-Refactor cycle: write a failing test, write minimal code to make it pass, then refactor. No implementation code is written without a failing test first.
Instructions
When building features or fixing bugs, follow TDD strictly:
The Red-Green-Refactor Cycle
RED: Write a Failing Test
// Step 1: Write the test FIRST describe('ShoppingCart', () => { it('should start with 0 items', () => { const cart = new ShoppingCart(); expect(cart.itemCount).toBe(0); }); }); // Run it — it should FAIL (ShoppingCart doesn't exist yet) // $ npx jest -- ShoppingCart // FAIL: Cannot find module 'ShoppingCart'
GREEN: Minimal Implementation
// Step 2: Write ONLY enough code to make the test pass class ShoppingCart { get itemCount(): number { return 0; // Simplest thing that works } } // Run again — should PASS // $ npx jest -- ShoppingCart // PASS: 1 test passed
REFACTOR: Improve Without Changing Behavior
// Step 3: Clean up while keeping tests green // In this case, nothing to refactor yet. Move to next test.
Iterative Feature Building
// Cycle 2: Add items it('should increase count when item added', () => { const cart = new ShoppingCart(); cart.addItem({ id: '1', name: 'Widget', price: 9.99 }); expect(cart.itemCount).toBe(1); }); // RED — addItem doesn't exist. Write it. // Cycle 3: Calculate total it('should calculate total price', () => { const cart = new ShoppingCart(); cart.addItem({ id: '1', name: 'Widget', price: 9.99 }); cart.addItem({ id: '2', name: 'Gadget', price: 14.99 }); expect(cart.total).toBe(24.98); }); // RED — total doesn't exist. Write it. // Cycle 4: Remove items it('should remove items by id', () => { const cart = new ShoppingCart(); cart.addItem({ id: '1', name: 'Widget', price: 9.99 }); cart.removeItem('1'); expect(cart.itemCount).toBe(0); expect(cart.total).toBe(0); }); // RED — removeItem doesn't exist. Write it. // Cycle 5: Edge cases it('should handle removing non-existent item', () => { const cart = new ShoppingCart(); expect(() => cart.removeItem('999')).not.toThrow(); expect(cart.itemCount).toBe(0); });
TDD for Bug Fixes
// Step 1: Write a test that reproduces the bug it('should handle floating point precision in totals', () => { const cart = new ShoppingCart(); cart.addItem({ id: '1', name: 'A', price: 0.1 }); cart.addItem({ id: '2', name: 'B', price: 0.2 }); // Bug: was returning 0.30000000000000004 expect(cart.total).toBe(0.3); }); // Step 2: Verify the test fails (reproduces the bug) // Step 3: Fix the implementation // Step 4: Verify the test passes
TDD Process Checklist
For EACH piece of functionality: 1. [ ] Write test describing desired behavior 2. [ ] Run test — verify it FAILS (red) 3. [ ] Write minimal code to pass 4. [ ] Run test — verify it PASSES (green) 5. [ ] Refactor if needed 6. [ ] Run ALL tests — verify nothing broke 7. [ ] Commit
Rules
- NEVER write implementation code before writing a failing test
- Each test should test ONE behavior
- Write the SIMPLEST code that makes the test pass — resist the urge to over-engineer
- Run the full test suite after each green-refactor cycle
- Commit after each successful cycle (small, frequent commits)
- If you realize you need a helper function, TDD that too
- Test names should read like specifications: "should [behavior] when [condition]"
- If a test is hard to write, it's a design signal — simplify the interface
- Never skip the RED step — if your test passes immediately, something is wrong
- Refactoring means changing structure without changing behavior — tests must stay green
Examples
User: Build a URL shortener service Action: TDD cycle: test create short URL -> implement, test redirect -> implement, test expiry -> implement, test collision handling -> implement
User: Fix the discount calculation bug Action: Write test reproducing the bug (red), fix calculation (green), refactor if needed
User: Add validation to the user registration Action: Write test for each validation rule (valid email, strong password, etc.), implement one at a time
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.