| name | tdd-workflow |
| description | Test-driven development workflow with comprehensive coverage requirements including unit, integration, and E2E tests |
| license | MIT |
| complexity | intermediate |
| time_to_learn | 30min |
| prerequisites | ["testing-patterns"] |
| tags | ["tdd","test-driven-development","red-green-refactor","coverage","quality"] |
| inputs | ["feature-requirements","source-code"] |
| outputs | ["test-suite","implementation-code"] |
| side_effects | ["creates-files","runs-commands"] |
| triggers | ["user-asks-about-tdd","user-asks-about-testing","file-type:*.test.ts","file-type:*.spec.py","testing-patterns","verification-loop"] |
| tier | core |
| metadata | {"source":"affaan-m/everything-Codex","adapted-by":"ai-skills","category":"development-workflow"} |
| governance_phases | ["build","prove"] |
| governance_norm_group | quality-gate |
| governance_auto_activate | true |
| organ_affinity | ["all"] |
| complements | ["backend-implementation-patterns","testing-patterns","verification-loop"] |
Test-Driven Development Workflow
Enforces test-driven development principles with comprehensive test coverage across all layers.
When to Activate
- Writing new features or functionality
- Fixing bugs or issues
- Refactoring existing code
- Adding API endpoints
- Creating new components
- Implementing business logic
Core Principles
1. Tests BEFORE Code
Always write tests first, then implement code to make tests pass. No exceptions.
2. Coverage Requirements
- Minimum 80% coverage (unit + integration + E2E)
- All edge cases covered
- Error scenarios tested
- Boundary conditions verified
- Happy path and sad path
3. Test Pyramid
┌────────┐
│ E2E │ (10-20%)
├────────┤
│ INTEG │ (20-30%)
├────────┤
│ UNIT │ (50-70%)
└────────┘
TDD Workflow: Red-Green-Refactor
Step 1: RED - Write Failing Test
Start with the user story:
As a [role], I want to [action], so that [benefit]
Example:
As a user, I want to search for products by category,
so that I can find relevant items quickly.
Write the test:
describe('ProductSearch', () => {
it('returns products filtered by category', async () => {
const products = await searchProducts({ category: 'electronics' });
expect(products).toHaveLength(5);
expect(products.every(p => p.category === 'electronics')).toBe(true);
});
});
Step 2: Run Tests (They Should Fail)
npm test
This is good! Red phase confirms test is working.
Step 3: GREEN - Implement Minimal Code
Write just enough code to pass:
export async function searchProducts(filters: SearchFilters) {
const { category } = filters;
return db.products.findMany({
where: { category }
});
}
Step 4: Run Tests (They Should Pass)
npm test
Step 5: REFACTOR - Improve Code
Now refactor while keeping tests green:
export async function searchProducts(filters: SearchFilters) {
const query = buildSearchQuery(filters);
const results = await executeSearch(query);
return transformResults(results);
}
Run tests again to ensure they still pass.
Test Types
Unit Tests
Purpose: Test individual functions in isolation
describe('calculateDiscount', () => {
it('applies 10% discount for basic tier', () => {
const price = calculateDiscount(100, 'basic');
expect(price).toBe(90);
});
it('applies 20% discount for premium tier', () => {
const price = calculateDiscount(100, 'premium');
expect(price).toBe(80);
});
it('throws error for invalid tier', () => {
expect(() => calculateDiscount(100, 'invalid')).toThrow();
});
});
Integration Tests
Purpose: Test multiple components working together
describe('User Registration API', () => {
it('creates user and sends welcome email', async () => {
const response = await request(app)
.post('/api/register')
.send({ email: 'test@example.com', password: 'secret' });
expect(response.status).toBe(201);
expect(response.body.user.email).toBe('test@example.com');
const sentEmails = await testEmailService.getSentEmails();
expect(sentEmails).toHaveLength(1);
expect(sentEmails[0].to).toBe('test@example.com');
});
});
E2E Tests (Playwright/Cypress)
Purpose: Test complete user flows through the UI
test('user can complete checkout process', async ({ page }) => {
await page.goto('/products');
await page.click('[data-testid="add-to-cart"]');
await page.click('[data-testid="cart"]');
await page.click('[data-testid="checkout"]');
await page.fill('[name="cardNumber"]', '4242424242424242');
await page.click('[data-testid="complete-order"]');
await expect(page.locator('.success-message')).toBeVisible();
await expect(page).toHaveURL(/\/order-confirmation/);
});
Coverage Verification
After implementation, check coverage:
npm test -- --coverage
Requirements:
- Statements: > 80%
- Branches: > 75%
- Functions: > 85%
- Lines: > 80%
Edge Cases Checklist
Always test:
Mocking Strategy
When to Mock
- External APIs
- Database calls (in unit tests)
- Time-dependent functions
- File system operations
- Third-party services
Example Mocks
vi.mock('./emailService', () => ({
sendEmail: vi.fn().mockResolvedValue({ success: true })
}));
vi.mock('./db', () => ({
users: {
findUnique: vi.fn().mockResolvedValue({ id: 1, name: 'Test' })
}
}));
vi.spyOn(Date, 'now').mockReturnValue(1234567890000);
Test Organization
src/
features/
products/
product.service.ts
product.service.test.ts # Unit tests
product.integration.test.ts # Integration tests
product.e2e.test.ts # E2E tests
Debugging Failed Tests
npm test -- product.service.test.ts
npm test -- -t "calculates discount correctly"
npm test -- --watch
npm test -- --coverage --no-cache
Integration Points
Complements:
- verification-loop: For pre-commit verification
- testing-patterns: For test design patterns
- deployment-cicd: For CI test execution
- security-implementation-guide: For security testing
Workflow Summary
- RED: Write failing test
- GREEN: Implement minimal code
- REFACTOR: Improve while keeping tests green
- VERIFY: Check coverage meets requirements
- COMMIT: Only commit if all tests pass
Never skip steps. Never commit untested code.
Related Skills
Complementary Skills (Use Together)
Alternative Skills (Similar Purpose)
- None - TDD is a specific methodology that complements other testing approaches
Prerequisite Skills (Learn First)