tdd-workflow
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
# ✗ ProductSearch > returns products filtered by category
# TypeError: searchProducts is not a function
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
# ✓ ProductSearch > returns products filtered by category (42ms)
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' }); // allow-secret
expect(response.status).toBe(201);
expect(response.body.user.email).toBe('test@example.com');
// Verify email was sent
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
# Output:
# File | % Stmts | % Branch | % Funcs | % Lines
# --------------|---------|----------|---------|--------
# All files | 84.2 | 78.5 | 91.3 | 85.1
Requirements:
- Statements: > 80%
- Branches: > 75%
- Functions: > 85%
- Lines: > 80%
Edge Cases Checklist
Always test:
- Empty input
- Null/undefined values
- Large datasets
- Concurrent operations
- Network failures
- Database errors
- Invalid data types
- Boundary values (0, -1, MAX_INT)
- Unauthorized access
- Rate limiting
Mocking Strategy
When to Mock
- External APIs
- Database calls (in unit tests)
- Time-dependent functions
- File system operations
- Third-party services
Example Mocks
// Mock external service
vi.mock('./emailService', () => ({
sendEmail: vi.fn().mockResolvedValue({ success: true })
}));
// Mock database
vi.mock('./db', () => ({
users: {
findUnique: vi.fn().mockResolvedValue({ id: 1, name: 'Test' })
}
}));
// Mock Date.now()
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
# Run single test file
npm test -- product.service.test.ts
# Run single test
npm test -- -t "calculates discount correctly"
# Run in watch mode
npm test -- --watch
# Run with coverage
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)
- testing-patterns - Comprehensive test patterns for unit, integration, and E2E tests
- verification-loop - Pre-commit verification workflow that validates all quality gates
- deployment-cicd - CI pipeline setup for automated test execution
Alternative Skills (Similar Purpose)
- None - TDD is a specific methodology that complements other testing approaches
Prerequisite Skills (Learn First)
- testing-patterns - Understanding test types and frameworks helps with TDD
More from 4444j99/a-i--skills
creative-writing-craft
Craft compelling fiction and creative nonfiction with attention to structure, voice, prose style, and revision. Supports short stories, novel chapters, essays, and hybrid forms. Triggers on creative writing, fiction writing, story craft, prose style, or literary technique requests.
186skill-creator
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
15freelance-client-ops
Manage freelance and client work professionally—proposals, contracts, scope management, invoicing, and client communication. Covers the business side of creative work. Triggers on freelance, client work, proposals, contracts, pricing, or project scope requests.
14generative-music-composer
Creates algorithmic music composition systems using procedural generation, Markov chains, L-systems, and neural approaches for ambient, adaptive, and experimental music.
12generative-art-algorithms
Create algorithmic and generative art using mathematical patterns, noise functions, particle systems, and procedural generation. Covers flow fields, L-systems, fractals, and creative coding foundations. Triggers on generative art, algorithmic art, creative coding, procedural generation, or mathematical visualization requests.
10interfaith-sacred-geometry
Generate sacred geometry patterns with interfaith symbolism for spiritual visualizations and art. Use when creating visual representations that honor multiple religious traditions, designing meditation aids, building soul journey visualizations, or producing art that bridges sacred traditions through geometric harmony. Triggers on sacred geometry requests, interfaith symbol design, spiritual visualization projects, or multi-tradition sacred art.
8