docs: 添加测试质量完善设计文档

新增文件:
- docs/superpowers/specs/2026-04-09-test-quality-improvement-design.md

设计内容:
1. 总体目标:1-2周内全面完善测试质量
2. 实施策略:测试优先方案(7天)
3. 详细计划:
   - 第1-2天:修复现有测试
   - 第3-5天:补充测试覆盖
   - 第6-7天:建立基础设施
4. 技术方案:测试分层架构、数据管理、CI/CD配置
5. 成功标准:覆盖率、稳定性、可维护性指标
6. 风险管理:风险识别和缓解措施
7. 后续演进:短期、中期、长期规划

关键指标:
- 测试通过率:100%
- 覆盖率:单元70%+、集成20%+、E2E 10%
- 执行速度:快速层<2分钟、标准层<10分钟、深度层<30分钟
- CI/CD稳定性:连续10次构建无失败
This commit is contained in:
张翔
2026-04-09 16:02:43 +08:00
parent ef056a10e5
commit 95a4fd89ee
@@ -0,0 +1,737 @@
# 测试质量完善设计文档
**日期:** 2026-04-09
**版本:** 1.0
**状态:** 待审查
---
## 一、背景与目标
### 1.1 项目现状
**已完成工作:**
- ✅ 企业官网核心功能(首页、服务、产品、案例、新闻、联系)
- ✅ CMS管理后台(内容管理、用户管理)
- ✅ 测试架构重构(Page Object Model、测试固件、分层测试)
- ✅ 冒烟测试全部通过(8/8
- ✅ CI/CD流水线配置
**待优化工作:**
- ⚠️ 用户旅程测试(3/12通过)
- ⚠️ 功能测试(待验证)
- ⚠️ 测试覆盖率不足
- ⚠️ 缺乏测试规范和工具支持
### 1.2 核心目标
**总体目标:** 在1-2周内全面完善测试质量,建立稳定、高效、可维护的测试体系
**关键指标:**
- ✅ 所有测试通过率:100%
- ✅ 代码覆盖率:单元测试70%+、集成测试20%+、E2E测试10%
- ✅ 测试执行速度:快速层<2分钟、标准层<10分钟、深度层<30分钟
- ✅ CI/CD稳定性:连续10次构建无失败
---
## 二、实施策略
### 2.1 实施方案:测试优先
**选择理由:**
1. 快速反馈 - 立即修复失败的测试,让CI/CD流水线恢复健康
2. 渐进式学习 - 在修复测试过程中深入理解代码和痛点
3. 降低风险 - 先让现有测试工作起来,再考虑扩展
4. 符合实际 - 当前已有测试架构基础,优先修复比从零建立更实际
### 2.2 时间规划
**总时长:** 7天(1周)
**阶段划分:**
- 第1-2天:修复现有测试
- 第3-5天:补充测试覆盖
- 第6-7天:建立基础设施
---
## 三、详细实施计划
### 3.1 第1-2天:修复现有测试
#### 目标
让所有现有测试通过,恢复CI/CD流水线健康
#### 任务清单
**第1天:修复用户旅程测试**
1. **修复页面加载超时问题**
- 为所有 `page.goto()` 添加 `{ waitUntil: 'domcontentloaded' }` 选项
- 增加断言超时时间到10秒
- 优化页面等待策略
2. **修复元素定位问题**
- 使用 `getByRole()` 替代 `locator()` 避免严格模式冲突
- 使用更精确的选择器(如 `getByTestId()`
- 处理动态元素和异步加载
3. **优化测试数据管理**
- 确保测试数据唯一性(使用时间戳)
- 添加测试数据清理逻辑
- 验证测试固件正确性
**第2天:修复功能测试和验证稳定性**
1. **修复功能测试**
- 验证内容管理测试(CRUD操作)
- 验证用户管理测试
- 验证前端响应式和无障碍测试
2. **验证测试稳定性**
- 本地运行所有测试3次,确保100%通过
- 修复偶发性失败(flaky tests
- 优化测试执行顺序
#### 交付物
- ✅ 所有测试通过(40/40
- ✅ 测试执行报告
- ✅ 问题修复记录文档
---
### 3.2 第3-5天:补充测试覆盖
#### 目标
达到分层覆盖率目标:单元测试70%+、集成测试20%+、E2E测试10%
#### 任务清单
**第3天:单元测试(目标70%+**
1. **核心业务逻辑单元测试**
- 内容管理服务(ContentService
- 用户管理服务(UserService
- 邮件服务(EmailService
- 文件上传服务(FileService
2. **工具函数单元测试**
- 数据验证工具(validation.ts
- 格式化工具(format.ts
- 加密工具(crypto.ts
- 日期处理工具(date.ts
3. **组件单元测试**
- UI组件(Button、Input、Modal等)
- 表单组件(ContactForm、ContentForm等)
- 布局组件(Header、Footer、Navigation等)
**第4天:集成测试(目标20%+**
1. **API集成测试**
- 内容管理API/api/content/*
- 用户管理API/api/users/*
- 认证API/api/auth/*
- 文件上传API/api/upload/*
2. **数据库集成测试**
- Drizzle ORM查询测试
- 数据库事务测试
- 数据库迁移测试
3. **组件集成测试**
- 表单提交流程
- 数据展示流程
- 用户交互流程
**第5天:E2E测试(目标10%+**
1. **完善用户旅程测试**
- 访客浏览旅程(已修复)
- 用户认证旅程(已修复)
- 管理员内容发布旅程(已修复)
2. **添加关键业务流程测试**
- 内容发布完整流程
- 用户注册登录流程
- 联系表单提交流程
3. **添加异常场景测试**
- 网络错误处理
- 表单验证错误
- 权限不足场景
#### 交付物
- ✅ 覆盖率报告(单元70%+、集成20%+、E2E 10%
- ✅ 新增测试用例清单
- ✅ 测试覆盖率趋势图
---
### 3.3 第6-7天:建立基础设施
#### 目标
建立完整的测试可维护性体系
#### 任务清单
**第6天:规范和文档**
1. **编写测试规范**
- 测试命名约定
```typescript
// 单元测试:[模块名].test.ts
// 集成测试:[模块名].integration.test.ts
// E2E测试:[功能名].spec.ts
// 测试用例命名:should_[期望行为]_when_[条件]
test('should_return_user_when_valid_id_provided', () => {
// ...
});
```
- 测试文件结构
```
tests/
├── unit/ # 单元测试
├── integration/ # 集成测试
└── e2e/ # E2E测试
├── smoke/ # 冒烟测试
├── journeys/ # 用户旅程测试
└── features/ # 功能测试
```
- 测试数据管理规范
- 使用测试固件工厂模式
- 测试数据隔离
- 自动清理机制
- 断言最佳实践
- 使用语义化断言
- 避免多重断言
- 清晰的错误消息
2. **编写测试指南**
- 单元测试编写指南
- Jest配置和最佳实践
- Mock和Stub使用
- 测试覆盖率要求
- 集成测试编写指南
- 测试环境配置
- 数据库测试策略
- API测试策略
- E2E测试编写指南
- Playwright配置和最佳实践
- Page Object Model使用
- 测试固件使用
- 测试调试技巧
- 常见问题排查
- 调试工具使用
- 性能优化技巧
**第7天:工具和CI/CD**
1. **创建测试脚手架工具**
- 单元测试生成器
```bash
npm run test:generate:unit -- --name UserService
# 生成: tests/unit/services/UserService.test.ts
```
- Page Object生成器
```bash
npm run test:generate:page -- --name AdminDashboard
# 生成: e2e/pages/AdminDashboardPage.ts
```
- 测试数据生成器
```bash
npm run test:generate:data -- --type user
# 生成: tests/fixtures/users.ts
```
2. **配置CI/CD质量门禁**
- 快速层:每次提交运行
```yaml
# 触发条件:每次push
# 运行内容:冒烟测试
# 超时时间:5分钟
# 失败策略:阻止合并
```
- 标准层:每次PR运行
```yaml
# 触发条件:PR创建/更新
# 运行内容:核心功能测试
# 超时时间:15分钟
# 失败策略:阻止合并
```
- 深度层:合并到主分支运行
```yaml
# 触发条件:合并到main
# 运行内容:完整测试套件
# 超时时间:45分钟
# 失败策略:通知团队
```
3. **建立测试监控**
- 测试覆盖率趋势监控
- 每日覆盖率报告
- 覆盖率下降告警
- 覆盖率趋势图
- 测试失败告警
- 实时失败通知
- 失败原因分析
- 历史失败统计
- 测试性能监控
- 测试执行时间趋势
- 慢测试识别
- 性能优化建议
#### 交付物
- ✅ 测试规范文档(`docs/testing/standards.md`
- ✅ 测试指南文档(`docs/testing/guide.md`
- ✅ 测试脚手架工具(`scripts/test-generators/`
- ✅ CI/CD配置更新(`.github/workflows/test.yml`
- ✅ 测试监控面板(`docs/testing/monitoring.md`
---
## 四、技术方案
### 4.1 测试分层架构
```
测试金字塔
/\
/ \ E2E测试 (10%)
/----\
/ \ 集成测试 (20%)
/--------\
/ \ 单元测试 (70%)
/----------\
```
**分层策略:**
| 层级 | 测试类型 | 数量 | 执行时间 | 触发条件 | 覆盖率目标 |
|------|---------|------|---------|---------|-----------|
| 快速层 | 冒烟测试 | 8个 | <2分钟 | 每次提交 | 核心功能 |
| 标准层 | 核心功能测试 | 30个 | <10分钟 | 每次PR | 主要业务流程 |
| 深度层 | 完整套件 | 40个 | <30分钟 | 合并到main | 全面覆盖 |
### 4.2 测试数据管理
**方案:** 使用测试固件工厂模式
```typescript
// tests/fixtures/factory.ts
import { faker } from '@faker-js/faker';
export const TestDataFactory = {
createUser: (overrides?: Partial<User>) => ({
id: faker.string.uuid(),
email: faker.internet.email(),
name: faker.person.fullName(),
role: 'user',
createdAt: new Date(),
...overrides,
}),
createContent: (overrides?: Partial<Content>) => ({
id: faker.string.uuid(),
title: faker.lorem.sentence(),
content: faker.lorem.paragraphs(),
type: 'news',
status: 'draft',
authorId: faker.string.uuid(),
createdAt: new Date(),
...overrides,
}),
createAdminUser: () => ({
email: 'admin@test.com',
password: 'Admin123!@#',
name: 'Test Admin',
role: 'admin',
}),
};
```
**使用示例:**
```typescript
// 单元测试
import { TestDataFactory } from '@/tests/fixtures/factory';
test('should create user', () => {
const user = TestDataFactory.createUser({ name: 'John' });
expect(user.name).toBe('John');
});
// E2E测试
import { testFixtures } from '@/e2e/fixtures/test-data';
test('admin login', async ({ page }) => {
const admin = testFixtures.adminUser;
await page.fill('#email', admin.email);
await page.fill('#password', admin.password);
});
```
### 4.3 Page Object Model
**规范:**
```typescript
// e2e/pages/BasePage.ts
export abstract class BasePage {
constructor(protected page: Page) {}
async goto(path: string) {
await this.page.goto(path, { waitUntil: 'domcontentloaded' });
}
async waitForLoad() {
await this.page.waitForLoadState('networkidle');
}
}
// e2e/pages/AdminContentPage.ts
export class AdminContentPage extends BasePage {
async goto() {
await super.goto('/admin/content');
}
async createContent(data: ContentData) {
await this.page.click('button:has-text("新建内容")');
await this.page.fill('#title', data.title);
await this.page.fill('#content', data.content);
await this.page.click('button[type="submit"]');
}
async expectContentInList(title: string) {
await expect(this.page.locator(`text=${title}`)).toBeVisible();
}
}
```
### 4.4 CI/CD质量门禁
```yaml
# .github/workflows/test.yml
name: Test Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
# 快速层:冒烟测试
quick-tests:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run smoke tests
run: npm run test:smoke
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: smoke-test-results
path: test-results/
# 标准层:核心功能测试
standard-tests:
runs-on: ubuntu-latest
needs: quick-tests
timeout-minutes: 15
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run standard tests
run: npm run test:standard
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
files: ./coverage/lcov.info
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: standard-test-results
path: test-results/
# 深度层:完整测试套件
deep-tests:
runs-on: ubuntu-latest
needs: standard-tests
timeout-minutes: 45
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run all tests
run: npm run test:deep
- name: Generate coverage report
run: npm run test:coverage
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
files: ./coverage/lcov.info
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: deep-test-results
path: test-results/
```
---
## 五、成功标准
### 5.1 第1-2天验收标准
**测试通过率:**
- ✅ 所有测试通过(40/40
- ✅ 本地运行3次无失败
- ✅ CI/CD流水线绿色
**测试稳定性:**
- ✅ 无flaky tests
- ✅ 测试执行时间稳定
- ✅ 测试结果可重复
### 5.2 第3-5天验收标准
**覆盖率目标:**
- ✅ 单元测试覆盖率 ≥ 70%
- ✅ 集成测试覆盖率 ≥ 20%
- ✅ E2E测试覆盖率 ≥ 10%
- ✅ 总体覆盖率 ≥ 60%
**测试质量:**
- ✅ 所有新增测试通过
- ✅ 测试代码符合规范
- ✅ 测试文档完整
### 5.3 第6-7天验收标准
**文档完整性:**
- ✅ 测试规范文档完成
- ✅ 测试指南文档完成
- ✅ 示例代码完整
**工具可用性:**
- ✅ 测试脚手架工具可用
- ✅ 工具文档完整
- ✅ 工具测试通过
**CI/CD配置:**
- ✅ 质量门禁生效
- ✅ 测试监控上线
- ✅ 告警机制正常
### 5.4 最终验收标准
**稳定性:**
- ✅ 连续10次CI/CD构建成功
- ✅ 无测试失败
- ✅ 无性能退化
**效率:**
- ✅ 测试执行时间符合预期
- ✅ 快速层<2分钟
- ✅ 标准层<10分钟
- ✅ 深度层<30分钟
**可维护性:**
- ✅ 团队能使用工具快速编写测试
- ✅ 测试文档清晰易懂
- ✅ 新成员能快速上手
---
## 六、风险管理
### 6.1 风险识别
| 风险 | 概率 | 影响 | 风险等级 |
|------|------|------|---------|
| 测试修复时间超出预期 | 中 | 高 | 高 |
| 覆盖率目标难以达成 | 中 | 中 | 中 |
| 工具开发时间不足 | 低 | 中 | 低 |
| 团队成员不熟悉新规范 | 中 | 中 | 中 |
| CI/CD配置复杂 | 低 | 高 | 中 |
### 6.2 缓解措施
**风险1:测试修复时间超出预期**
- **缓解措施:** 优先修复高优先级测试,低优先级测试可延后
- **应急方案:** 调整时间计划,增加1天缓冲时间
- **责任人:** 测试负责人
**风险2:覆盖率目标难以达成**
- **缓解措施:** 聚焦核心业务逻辑,非关键代码可适当降低要求
- **应急方案:** 调整覆盖率目标,单元测试降至60%
- **责任人:** 开发负责人
**风险3:工具开发时间不足**
- **缓解措施:** 先提供基础功能,后续迭代完善
- **应急方案:** 手动创建测试,工具延后开发
- **责任人:** 工具开发负责人
**风险4:团队成员不熟悉新规范**
- **缓解措施:** 提供详细文档和示例,安排培训时间
- **应急方案:** 一对一辅导,逐步推广
- **责任人:** 团队负责人
**风险5CI/CD配置复杂**
- **缓解措施:** 参考成熟项目配置,逐步调试
- **应急方案:** 简化配置,分阶段实施
- **责任人:** DevOps负责人
---
## 七、后续演进
### 7.1 短期优化(1个月内)
1. **测试性能优化**
- 优化测试执行速度
- 减少测试资源消耗
- 提升测试稳定性
2. **工具功能增强**
- 增加测试生成器功能
- 优化测试报告展示
- 增加测试调试工具
3. **文档持续完善**
- 根据反馈更新文档
- 增加更多示例
- 制作视频教程
### 7.2 中期规划(3个月内)
1. **测试智能化**
- 引入AI辅助测试生成
- 自动化测试数据生成
- 智能测试推荐
2. **测试可视化**
- 测试覆盖率可视化
- 测试执行趋势分析
- 测试质量评分
3. **测试治理**
- 测试代码质量检查
- 测试债务管理
- 测试重构计划
### 7.3 长期愿景(6个月内)
1. **测试平台化**
- 统一测试管理平台
- 测试资产沉淀
- 测试知识库建设
2. **测试标准化**
- 建立测试标准体系
- 测试最佳实践库
- 测试培训体系
3. **测试文化**
- 测试驱动开发文化
- 质量意识提升
- 持续改进机制
---
## 八、附录
### 8.1 参考资源
**测试框架文档:**
- [Jest官方文档](https://jestjs.io/)
- [Playwright官方文档](https://playwright.dev/)
- [Testing Library文档](https://testing-library.com/)
**最佳实践:**
- [Google Testing Blog](https://testing.googleblog.com/)
- [Martin Fowler - Testing](https://martinfowler.com/testing/)
- [Test Pyramid](https://martinfowler.com/articles/practical-test-pyramid.html)
**工具和库:**
- [@faker-js/faker](https://fakerjs.dev/)
- [MSW - Mock Service Worker](https://mswjs.io/)
- [Codecov](https://codecov.io/)
### 8.2 术语表
| 术语 | 定义 |
|------|------|
| 单元测试 | 测试单个函数或组件的测试 |
| 集成测试 | 测试多个模块集成的测试 |
| E2E测试 | 端到端测试,模拟用户真实操作 |
| 冒烟测试 | 快速验证核心功能的测试 |
| 测试覆盖率 | 代码被测试覆盖的比例 |
| Flaky Test | 偶发性失败的测试 |
| Page Object Model | 页面对象模型,封装页面操作 |
| 测试固件 | 测试数据和环境的固定配置 |
### 8.3 联系方式
**项目负责人:** 张翔
**技术支持:** 开发团队
**问题反馈:** 项目Issue跟踪系统
---
**文档版本历史:**
| 版本 | 日期 | 作者 | 变更说明 |
|------|------|------|---------|
| 1.0 | 2026-04-09 | 张翔 | 初始版本 |