| name | compose:tdd |
| description | Use when implementing any feature or bugfix, before writing implementation code |
Test-Driven Development (TDD)
Overview
Write the test first. Watch it fail. Write minimal code to pass.
The Iron Law
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
Red-Green-Refactor
- RED — Write one failing test
- GREEN — Write minimal code to pass
- REFACTOR — Clean up while staying green
- Repeat — back to RED with the next behavior
RED - Write Failing Test
Write one minimal test showing what should happen.
test('retries failed operations 3 times', async () => {
let attempts = 0;
const operation = () => {
attempts++;
if (attempts < 3) throw new Error('fail');
return 'success';
};
const result = await retryOperation(operation);
expect(result).toBe('success');
expect(attempts).toBe(3);
});
Verify RED - Watch It Fail
MANDATORY. Never skip.
npm test path/to/test.test.ts
Confirm:
- Test fails (not errors)
- Failure message is expected
- Fails because feature missing (not typos)
GREEN - Minimal Code
Write simplest code to pass the test.
async function retryOperation<T>(fn: () => Promise<T>): Promise<T> {
for (let i = 0; i < 3; i++) {
try {
return await fn();
} catch (e) {
if (i === 2) throw e;
}
}
throw new Error('unreachable');
}
Verify GREEN - Watch It Pass
MANDATORY.
npm test path/to/test.test.ts
Confirm:
- Test passes
- Other tests still pass
REFACTOR - Clean Up
After green only:
- Remove duplication
- Improve names
- Extract helpers
Keep tests green. Don't add behavior.