| name | tdd-workflow |
| description | Test-driven development workflow. Use when writing tests, implementing features with TDD, or ensuring test coverage. Covers red-green-refactor cycle, test quality, and coverage requirements. |
Test-Driven Development Workflow
Mandatory TDD process for feature implementation.
The TDD Cycle
1. RED → Write failing tests first
2. GREEN → Implement minimum code to pass
3. REFACTOR → Improve code while keeping tests green
4. COMMIT → Commit at each milestone
Phase 0: Research First
Before writing any tests:
- Detect technology stack - Check package.json, existing patterns
- Research testing framework - Jest patterns for this project
- Analyze existing tests - Follow established conventions
- Understand requirements - Break down acceptance criteria
Phase 1: Write Failing Tests
describe('Feature: Company Documents', () => {
describe('GET /api/companies/:id/documents', () => {
it('returns documents for company member', async () => {
const { token, company } = await createTestUser({ role: 'MEMBER' });
const response = await request(app)
.get(`/api/companies/${company.id}/documents`)
.set('Authorization', `Bearer ${token}`);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
});
it('returns 403 for non-member', async () => {
});
it('returns 401 without auth token', async () => {
});
});
});
Test Categories
- Happy path - Normal successful operations
- Permission scenarios - Auth and authorization
- Validation scenarios - Input validation failures
- Error scenarios - 404, 500, edge cases
Phase 2: Implement to Pass
Write minimum code to make tests pass:
- Don't over-engineer
- Don't add untested features
- Focus on passing the current test
Phase 3: Refactor
With green tests:
- Improve code quality
- Remove duplication
- Enhance readability
- Keep tests passing after each change
Coverage Requirements
- Target: 80%+ coverage on new code
- Critical paths: 100% coverage
- Focus areas:
- All CRUD operations
- Permission checks
- Error handling
- Business logic
Test Quality Standards
Naming
it('returns 403 when user lacks MANAGE_COMPANY permission')
it('calls requirePermission middleware')
Structure (AAA Pattern)
it('creates document successfully', async () => {
const company = await createTestCompany();
const user = await createTestUser({ companyId: company.id });
const response = await request(app)
.post(`/api/companies/${company.id}/documents`)
.set('Authorization', `Bearer ${user.token}`)
.attach('file', Buffer.from('test'), 'test.txt');
expect(response.status).toBe(201);
expect(response.body.data.filename).toBe('test.txt');
});
Independence
- Each test should run independently
- Use
beforeEach for setup, afterEach for cleanup
- Don't depend on test execution order
Commit Points
- After test suite complete:
test: add tests for [feature]
- After implementation passes:
feat: implement [feature]
- After refactoring:
refactor: improve [aspect]
Quality Gates
Before marking phase complete:
Files Reference
backend/src/__tests__/ - Backend tests
frontend/src/__tests__/ - Frontend tests
jest.config.js - Jest configuration
Anti-Patterns
- Testing implementation details - Test behavior, not internals
- Flaky tests - Fix immediately, never ignore
- Test pollution - Clean up after each test
- Slow tests - Mock external services
- Testing framework code - Trust Jest/testing-library