--- description: globs: alwaysApply: true --- # Test Workflow & Development Process ## **Test-Driven Development (TDD) Integration** ### **Core TDD Cycle with Jest** ```bash # 1. Start development with watch mode npm run test:watch # 2. Write failing test first # Create test file: src/utils/newFeature.test.ts # Write test that describes expected behavior # 3. Implement minimum code to make test pass # 4. Refactor while keeping tests green # 5. Add edge cases and error scenarios ``` ### **TDD Workflow Per Subtask** ```bash # When starting a new subtask: task-master set-status --id=4.1 --status=in-progress # Begin TDD cycle: npm run test:watch # Keep running during development # Document TDD progress in subtask: task-master update-subtask --id=4.1 --prompt="TDD Progress: - Written 3 failing tests for core functionality - Implemented basic feature, tests now passing - Adding edge case tests for error handling" # Complete subtask with test summary: task-master update-subtask --id=4.1 --prompt="Implementation complete: - Feature implemented with 8 unit tests - Coverage: 95% statements, 88% branches - All tests passing, TDD cycle complete" ``` ## **Testing Commands & Usage** ### **Development Commands** ```bash # Primary development command - use during coding npm run test:watch # Watch mode with Jest npm run test:watch -- --testNamePattern="auth" # Watch specific tests # Targeted testing during development npm run test:unit # Run only unit tests npm run test:unit -- --coverage # Unit tests with coverage # Integration testing when APIs are ready npm run test:integration # Run integration tests npm run test:integration -- --detectOpenHandles # Debug hanging tests # End-to-end testing for workflows npm run test:e2e # Run E2E tests npm run test:e2e -- --timeout=30000 # Extended timeout for E2E ``` ### **Quality Assurance Commands** ```bash # Full test suite with coverage (before commits) npm run test:coverage # Complete coverage analysis # All tests (CI/CD pipeline) npm test # Run all test projects # Specific test file execution npm test -- auth.test.ts # Run specific test file npm test -- --testNamePattern="should handle errors" # Run specific tests ``` ## **Test Implementation Patterns** ### **Unit Test Development** ```typescript // ✅ DO: Follow established patterns from auth.test.ts describe('FeatureName', () => { beforeEach(() => { jest.clearAllMocks(); // Setup mocks with proper typing }); describe('functionName', () => { it('should handle normal case', () => { // Test implementation with specific assertions }); it('should throw error for invalid input', async () => { // Error scenario testing await expect(functionName(invalidInput)) .rejects.toThrow('Specific error message'); }); }); }); ``` ### **Integration Test Development** ```typescript // ✅ DO: Use supertest for API endpoint testing import request from 'supertest'; import { app } from '../../src/app'; describe('POST /api/auth/register', () => { beforeEach(async () => { await integrationTestUtils.cleanupTestData(); }); it('should register user successfully', async () => { const userData = createTestUser(); const response = await request(app) .post('/api/auth/register') .send(userData) .expect(201); expect(response.body).toMatchObject({ id: expect.any(String), email: userData.email }); // Verify database state const user = await prisma.user.findUnique({ where: { email: userData.email } }); expect(user).toBeTruthy(); }); }); ``` ### **E2E Test Development** ```typescript // ✅ DO: Test complete user workflows describe('User Authentication Flow', () => { it('should complete registration → login → protected access', async () => { // Step 1: Register const userData = createTestUser(); await request(app) .post('/api/auth/register') .send(userData) .expect(201); // Step 2: Login const loginResponse = await request(app) .post('/api/auth/login') .send({ email: userData.email, password: userData.password }) .expect(200); const { token } = loginResponse.body; // Step 3: Access protected resource await request(app) .get('/api/profile') .set('Authorization', `Bearer ${token}`) .expect(200); }, 30000); // Extended timeout for E2E }); ``` ## **Mocking & Test Utilities** ### **Established Mocking Patterns** ```typescript // ✅ DO: Use established bcrypt mocking pattern jest.mock('bcrypt'); import bcrypt from 'bcrypt'; const mockHash = bcrypt.hash as jest.MockedFunction; const mockCompare = bcrypt.compare as jest.MockedFunction; // ✅ DO: Use Prisma mocking for unit tests jest.mock('@prisma/client', () => ({ PrismaClient: jest.fn().mockImplementation(() => ({ user: { create: jest.fn(), findUnique: jest.fn(), }, $connect: jest.fn(), $disconnect: jest.fn(), })), })); ``` ### **Test Fixtures Usage** ```typescript // ✅ DO: Use centralized test fixtures import { createTestUser, adminUser, invalidUser } from '../fixtures/users'; describe('User Service', () => { it('should handle admin user creation', async () => { const userData = createTestUser(adminUser); // Test implementation }); it('should reject invalid user data', async () => { const userData = createTestUser(invalidUser); // Error testing }); }); ``` ## **Coverage Standards & Monitoring** ### **Coverage Thresholds** - **Global Standards**: 80% lines/functions, 70% branches - **Critical Code**: 90% utils, 85% middleware - **New Features**: Must meet or exceed global thresholds - **Legacy Code**: Gradual improvement with each change ### **Coverage Reporting & Analysis** ```bash # Generate coverage reports npm run test:coverage # View detailed HTML report open coverage/lcov-report/index.html # Coverage files generated: # - coverage/lcov-report/index.html # Detailed HTML report # - coverage/lcov.info # LCOV format for IDE integration # - coverage/coverage-final.json # JSON format for tooling ``` ### **Coverage Quality Checks** ```typescript // ✅ DO: Test all code paths describe('validateInput', () => { it('should return true for valid input', () => { expect(validateInput('valid')).toBe(true); }); it('should return false for various invalid inputs', () => { expect(validateInput('')).toBe(false); // Empty string expect(validateInput(null)).toBe(false); // Null value expect(validateInput(undefined)).toBe(false); // Undefined }); it('should throw for unexpected input types', () => { expect(() => validateInput(123)).toThrow('Invalid input type'); }); }); ``` ## **Testing During Development Phases** ### **Feature Development Phase** ```bash # 1. Start feature development task-master set-status --id=X.Y --status=in-progress # 2. Begin TDD cycle npm run test:watch # 3. Document test progress in subtask task-master update-subtask --id=X.Y --prompt="Test development: - Created test file with 5 failing tests - Implemented core functionality - Tests passing, adding error scenarios" # 4. Verify coverage before completion npm run test:coverage # 5. Update subtask with final test status task-master update-subtask --id=X.Y --prompt="Testing complete: - 12 unit tests with full coverage - All edge cases and error scenarios covered - Ready for integration testing" ``` ### **Integration Testing Phase** ```bash # After API endpoints are implemented npm run test:integration # Update integration test templates # Replace placeholder tests with real endpoint calls # Document integration test results task-master update-subtask --id=X.Y --prompt="Integration tests: - Updated auth endpoint tests - Database integration verified - All HTTP status codes and responses tested" ``` ### **Pre-Commit Testing Phase** ```bash # Before committing code npm run test:coverage # Verify all tests pass with coverage npm run test:unit # Quick unit test verification npm run test:integration # Integration test verification (if applicable) # Commit pattern for test updates git add tests/ src/**/*.test.ts git commit -m "test(task-X): Add comprehensive tests for Feature Y - Unit tests with 95% coverage (exceeds 90% threshold) - Integration tests for API endpoints - Test fixtures for data generation - Proper mocking patterns established Task X: Feature Y - Testing complete" ``` ## **Error Handling & Debugging** ### **Test Debugging Techniques** ```typescript // ✅ DO: Use test utilities for debugging import { testUtils } from '../setup'; it('should debug complex operation', () => { testUtils.withConsole(() => { // Console output visible only for this test console.log('Debug info:', complexData); service.complexOperation(); }); }); // ✅ DO: Use proper async debugging it('should handle async operations', async () => { const promise = service.asyncOperation(); // Test intermediate state expect(service.isProcessing()).toBe(true); const result = await promise; expect(result).toBe('expected'); expect(service.isProcessing()).toBe(false); }); ``` ### **Common Test Issues & Solutions** ```bash # Hanging tests (common with database connections) npm run test:integration -- --detectOpenHandles # Memory leaks in tests npm run test:unit -- --logHeapUsage # Slow tests identification npm run test:coverage -- --verbose # Mock not working properly # Check: mock is declared before imports # Check: jest.clearAllMocks() in beforeEach # Check: TypeScript typing is correct ``` ## **Continuous Integration Integration** ### **CI/CD Pipeline Testing** ```yaml # Example GitHub Actions integration - name: Run tests run: | npm ci npm run test:coverage - name: Upload coverage reports uses: codecov/codecov-action@v3 with: file: ./coverage/lcov.info ``` ### **Pre-commit Hooks** ```bash # Setup pre-commit testing (recommended) # In package.json scripts: "pre-commit": "npm run test:unit && npm run test:integration" # Husky integration example: npx husky add .husky/pre-commit "npm run test:unit" ``` ## **Test Maintenance & Evolution** ### **Adding Tests for New Features** 1. **Create test file** alongside source code or in `tests/unit/` 2. **Follow established patterns** from `src/utils/auth.test.ts` 3. **Use existing fixtures** from `tests/fixtures/` 4. **Apply proper mocking** patterns for dependencies 5. **Meet coverage thresholds** for the module ### **Updating Integration/E2E Tests** 1. **Update templates** in `tests/integration/` when APIs change 2. **Modify E2E workflows** in `tests/e2e/` for new user journeys 3. **Update test fixtures** for new data requirements 4. **Maintain database cleanup** utilities ### **Test Performance Optimization** - **Parallel execution**: Jest runs tests in parallel by default - **Test isolation**: Use proper setup/teardown for independence - **Mock optimization**: Mock heavy dependencies appropriately - **Database efficiency**: Use transaction rollbacks where possible --- **Key References:** - [Testing Standards](mdc:.cursor/rules/tests.mdc) - [Git Workflow](mdc:.cursor/rules/git_workflow.mdc) - [Development Workflow](mdc:.cursor/rules/dev_workflow.mdc) - [Jest Configuration](mdc:jest.config.js) - [Auth Test Example](mdc:src/utils/auth.test.ts)