# 渐进式测试覆盖率提升计划 > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** 建立可持续的测试覆盖率提升体系,从当前29.5%逐步提升到更高水平,同时保证开发效率和代码质量。 **Architecture:** 采用分层覆盖率策略,核心业务逻辑层高覆盖(70-80%),UI组件层中覆盖(60-70%),页面展示层适度覆盖(40-50%)。 **Tech Stack:** Jest, React Testing Library, Next.js, TypeScript, GitHub Actions --- ## 已完成任务 ### Task 1: 调整Jest配置覆盖率阈值 **Files:** - Modify: `jest.config.js:12-18` **Step 1: 修改覆盖率阈值为合理水平** ```javascript coverageThreshold: { global: { branches: 20, functions: 25, lines: 25, statements: 25, }, }, ``` **Step 2: 运行测试验证配置** Run: `npm run test:unit -- --coverage --coverageReporters=text-summary` Expected: PASS with coverage above 25% **Step 3: 提交配置修改** ```bash git add jest.config.js git commit -m "test: adjust coverage threshold to reasonable level (25%)" ``` --- ## 第一阶段:稳定当前覆盖率(1-2周) ### Task 2: 补充核心业务逻辑测试 **Files:** - Create: `src/lib/auth/session.test.ts` - Create: `src/lib/auth/token.test.ts` - Create: `src/lib/validation.test.ts` **Step 1: 为session管理编写测试** ```typescript describe('session management', () => { it('should create session with user data', () => { const session = createSession({ userId: '123', role: 'admin' }); expect(session).toBeDefined(); expect(session.userId).toBe('123'); }); it('should validate session expiration', () => { const expiredSession = createSession({ userId: '123', expiresIn: -1 }); expect(isSessionValid(expiredSession)).toBe(false); }); }); ``` **Step 2: 运行测试验证失败** Run: `npm run test:unit -- --testPathPattern="session.test.ts"` Expected: FAIL with "createSession not defined" **Step 3: 实现session管理功能** ```typescript export function createSession(userData: SessionData): Session { return { ...userData, createdAt: Date.now(), expiresAt: Date.now() + (24 * 60 * 60 * 1000), // 24小时 }; } export function isSessionValid(session: Session): boolean { return Date.now() < session.expiresAt; } ``` **Step 4: 运行测试验证通过** Run: `npm run test:unit -- --testPathPattern="session.test.ts"` Expected: PASS **Step 5: 提交** ```bash git add src/lib/auth/session.test.ts src/lib/auth/session.ts git commit -m "test: add session management tests" ``` --- ### Task 3: 补充数据验证测试 **Files:** - Create: `src/lib/validation.test.ts` - Modify: `src/lib/validation.ts` **Step 1: 编写数据验证测试** ```typescript describe('validation', () => { describe('email validation', () => { it('should accept valid email', () => { expect(validateEmail('test@example.com')).toBe(true); }); it('should reject invalid email', () => { expect(validateEmail('invalid')).toBe(false); }); }); describe('phone validation', () => { it('should accept valid phone', () => { expect(validatePhone('13800138000')).toBe(true); }); it('should reject invalid phone', () => { expect(validatePhone('123')).toBe(false); }); }); }); ``` **Step 2: 运行测试验证失败** Run: `npm run test:unit -- --testPathPattern="validation.test.ts"` Expected: FAIL with validation functions not defined **Step 3: 实现验证函数** ```typescript export function validateEmail(email: string): boolean { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } export function validatePhone(phone: string): boolean { const phoneRegex = /^1[3-9]\d{9}$/; return phoneRegex.test(phone); } ``` **Step 4: 运行测试验证通过** Run: `npm run test:unit -- --testPathPattern="validation.test.ts"` Expected: PASS **Step 5: 提交** ```bash git add src/lib/validation.test.ts src/lib/validation.ts git commit -m "test: add data validation tests" ``` --- ### Task 4: 优化测试执行性能 **Files:** - Modify: `jest.config.js` - Create: `.github/workflows/test-optimized.yml` **Step 1: 配置并行测试执行** ```javascript // jest.config.js module.exports = { // ... existing config maxWorkers: '50%', }; ``` **Step 2: 创建优化后的CI工作流** ```yaml # .github/workflows/test-optimized.yml name: Optimized Test on: [push, pull_request] jobs: test: runs-on: ubuntu-latest strategy: matrix: shard: [1, 2, 3, 4] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' - name: Install dependencies run: npm ci - name: Run tests (shard ${{ matrix.shard }}) run: npm run test:unit -- --shard=${{ matrix.shard }}/4 - name: Upload coverage if: matrix.shard == 4 uses: codecov/codecov-action@v4 ``` **Step 3: 提交配置** ```bash git add jest.config.js .github/workflows/test-optimized.yml git commit -m "ci: optimize test execution with parallelization" ``` --- ## 第二阶段:提升覆盖率到35%(1-2个月) ### Task 5: 补充API路由测试 **Files:** - Create: `src/app/api/contact/route.test.ts` - Create: `src/app/api/auth/route.test.ts` **Step 1: 编写API路由测试** ```typescript describe('/api/contact', () => { it('should handle POST request', async () => { const response = await POST(new Request('http://localhost/api/contact', { method: 'POST', body: JSON.stringify({ name: 'Test', email: 'test@example.com' }), })); expect(response.status).toBe(200); }); it('should validate required fields', async () => { const response = await POST(new Request('http://localhost/api/contact', { method: 'POST', body: JSON.stringify({}), })); expect(response.status).toBe(400); }); }); ``` **Step 2: 运行测试验证失败** Run: `npm run test:unit -- --testPathPattern="api/contact/route.test.ts"` Expected: FAIL with API route not tested **Step 3: 实现API路由验证逻辑** ```typescript // 确保API路由有适当的验证和错误处理 export async function POST(request: Request) { try { const body = await request.json(); if (!body.name || !body.email) { return Response.json({ error: 'Missing required fields' }, { status: 400 }); } // 处理逻辑... return Response.json({ success: true }, { status: 200 }); } catch (error) { return Response.json({ error: 'Internal server error' }, { status: 500 }); } } ``` **Step 4: 运行测试验证通过** Run: `npm run test:unit -- --testPathPattern="api/contact/route.test.ts"` Expected: PASS **Step 5: 提交** ```bash git add src/app/api/contact/route.test.ts src/app/api/contact/route.ts git commit -m "test: add API route tests" ``` --- ### Task 6: 补充数据库操作测试 **Files:** - Create: `src/db/queries.test.ts` - Create: `src/db/mutations.test.ts` **Step 1: 编写数据库查询测试** ```typescript describe('database queries', () => { it('should query user by id', async () => { const user = await getUserById('123'); expect(user).toBeDefined(); expect(user.id).toBe('123'); }); it('should return null for non-existent user', async () => { const user = await getUserById('non-existent'); expect(user).toBeNull(); }); }); ``` **Step 2: 运行测试验证失败** Run: `npm run test:unit -- --testPathPattern="db/queries.test.ts"` Expected: FAIL with database functions not tested **Step 3: 实现数据库查询函数** ```typescript export async function getUserById(id: string): Promise { const result = await db.select().from(users).where(eq(users.id, id)).limit(1); return result[0] || null; } ``` **Step 4: 运行测试验证通过** Run: `npm run test:unit -- --testPathPattern="db/queries.test.ts"` Expected: PASS **Step 5: 提交** ```bash git add src/db/queries.test.ts src/db/queries.ts git commit -m "test: add database query tests" ``` --- ### Task 7: 提升分支覆盖率 **Files:** - Modify: `src/lib/auth/permissions.test.ts` - Modify: `src/lib/upload.test.ts` **Step 1: 添加边界条件测试** ```typescript describe('permissions edge cases', () => { it('should handle null role', () => { expect(hasPermission(null, 'content', 'read')).toBe(false); }); it('should handle undefined resource', () => { expect(hasPermission('admin', undefined, 'read')).toBe(false); }); it('should handle empty action string', () => { expect(hasPermission('admin', 'content', '')).toBe(false); }); }); ``` **Step 2: 运行测试验证通过** Run: `npm run test:unit -- --testPathPattern="permissions.test.ts"` Expected: PASS with improved branch coverage **Step 3: 提交** ```bash git add src/lib/auth/permissions.test.ts git commit -m "test: improve branch coverage with edge cases" ``` --- ## 第三阶段:建立测试质量体系(2-3个月) ### Task 8: 创建测试指南文档 **Files:** - Create: `docs/testing-guide.md` **Step 1: 编写测试指南** ```markdown # 测试指南 ## 测试策略 本项目采用分层覆盖率策略: - 核心业务逻辑层:70-80%覆盖率 - UI组件层:60-70%覆盖率 - 页面展示层:40-50%覆盖率 ## 测试编写规范 ### 单元测试 - 使用Jest和React Testing Library - 遵循AAA模式(Arrange-Act-Assert) - 每个测试只验证一个行为 ### 集成测试 - 测试组件间的交互 - 使用真实的数据流 - 避免过度mock ## 常见问题 **Q: 如何处理异步测试?** A: 使用async/await和waitFor函数。 **Q: 如何测试错误处理?** A: 使用toThrow和expect.assertions验证错误路径。 ``` **Step 2: 提交文档** ```bash git add docs/testing-guide.md git commit -m "docs: add testing guide" ``` --- ### Task 9: 建立覆盖率趋势监控 **Files:** - Create: `scripts/coverage-trend.js` - Create: `.github/workflows/coverage-report.yml` **Step 1: 创建覆盖率趋势脚本** ```javascript // scripts/coverage-trend.js const fs = require('fs'); const coverage = JSON.parse(fs.readFileSync('coverage/coverage-final.json', 'utf8')); const metrics = { statements: coverage.total.statements.pct, branches: coverage.total.branches.pct, functions: coverage.total.functions.pct, lines: coverage.total.lines.pct, }; console.log(JSON.stringify(metrics, null, 2)); ``` **Step 2: 创建覆盖率报告工作流** ```yaml # .github/workflows/coverage-report.yml name: Coverage Report on: push: branches: [main] jobs: report: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Generate coverage run: | npm run test:unit -- --coverage node scripts/coverage-trend.js > coverage-metrics.json - name: Upload metrics uses: actions/upload-artifact@v4 with: name: coverage-metrics path: coverage-metrics.json ``` **Step 3: 提交** ```bash git add scripts/coverage-trend.js .github/workflows/coverage-report.yml git commit -m "ci: add coverage trend monitoring" ``` --- ### Task 10: 更新覆盖率目标 **Files:** - Modify: `jest.config.js` **Step 1: 提升覆盖率目标到35%** ```javascript coverageThreshold: { global: { branches: 25, functions: 35, lines: 35, statements: 35, }, }, ``` **Step 2: 运行测试验证** Run: `npm run test:unit -- --coverage --coverageReporters=text-summary` Expected: PASS with coverage above 35% **Step 3: 提交** ```bash git add jest.config.js git commit -m "test: increase coverage threshold to 35%" ``` --- ## 验证步骤 ### 验证1: 确认所有测试通过 Run: `npm run test:unit` Expected: All tests pass ### 验证2: 确认覆盖率达标 Run: `npm run test:unit -- --coverage --coverageReporters=text-summary` Expected: Coverage above 35% ### 验证3: 确认CI构建通过 Check: GitHub Actions workflow status Expected: All workflows pass --- ## 回滚计划 如果出现问题,可以回滚到之前的配置: ```bash git log --oneline --all git checkout ``` --- ## 相关资源 - [Jest文档](https://jestjs.io/docs/getting-started) - [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) - [测试最佳实践](https://github.com/goldbergyoni/javascript-testing-best-practices)