Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Guides the red-green-refactor TDD workflow: write a failing test first, implement the minimum code to make it pass, then refactor while keeping tests green. Use when a user asks to practice TDD, write tests first, follow red-green-refactor, do test-driven development, write failing tests before code, or phrases like 'make the test pass', 'test coverage', or 'unit tests before implementation'.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-11 | ✗→✓ | ▲ Improved | 72% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 86% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 133% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 33% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 42% | 0% |
You are following the RED-GREEN-REFACTOR cycle for test-driven development. Every new feature, bug fix, or behavior change starts with a failing test.
The test should be focused on ONE behavior, named descriptively, and use clear assertions.
Executable example (Jest):
js// calculateTotal.test.js const { calculateTotal } = require('./calculateTotal'); describe('calculateTotal', () => { it('should apply 10% discount when total exceeds 100', () => { const items = [{ price: 60 }, { price: 60 }]; // total = 120 expect(calculateTotal(items)).toBe(108); // 120 * 0.90 }); });
Running this now produces: Cannot find module './calculateTotal' — correct RED state.
Write the minimum code needed to pass the test. Don't add anything extra.
js// calculateTotal.js function calculateTotal(items) { const total = items.reduce((sum, item) => sum + item.price, 0); return total > 100 ? total * 0.9 : total; } module.exports = { calculateTotal };
Run the test — it passes. GREEN achieved. Stop here; resist adding more logic.
With a passing test as your safety net, clean up the implementation. Run tests after every change.
js// calculateTotal.js — refactored for clarity const DISCOUNT_THRESHOLD = 100; const DISCOUNT_RATE = 0.9; function calculateTotal(items) { const subtotal = items.reduce((sum, { price }) => sum + price, 0); return subtotal > DISCOUNT_THRESHOLD ? subtotal * DISCOUNT_RATE : subtotal; } module.exports = { calculateTotal };
Test still passes — GREEN maintained. Constants now communicate intent.
Next requirement: apply a 15% discount when total exceeds 200.
RED — write the failing test first:
jsit('should apply 15% discount when total exceeds 200', () => { const items = [{ price: 110 }, { price: 110 }]; // total = 220 expect(calculateTotal(items)).toBe(187); // 220 * 0.85 });
GREEN — extend the implementation minimally:
jsfunction calculateTotal(items) { const subtotal = items.reduce((sum, { price }) => sum + price, 0); if (subtotal > 200) return subtotal * 0.85; if (subtotal > 100) return subtotal * 0.9; return subtotal; }
REFACTOR — remove duplication with a tiered structure:
jsconst DISCOUNT_TIERS = [ { threshold: 200, rate: 0.85 }, { threshold: 100, rate: 0.9 }, ]; function calculateTotal(items) { const subtotal = items.reduce((sum, { price }) => sum + price, 0); const tier = DISCOUNT_TIERS.find(({ threshold }) => subtotal > threshold); return tier ? subtotal * tier.rate : subtotal; }
Both tests pass — ready for the next cycle.
Other measured skills in the registry, with their headline benchmark lift.