测试覆盖率提升策略设计规格
日期: 2026-04-26 | 状态: draft | 主题: 测试覆盖率 2% → 80%
1. 背景与目标
1.1 现状
HMS 健康管理平台当前测试覆盖极低:
- 后端: 461 单元测试 + 54 集成测试,但 erp-health 34 entity 中 27 个 service 零单元测试,erp-ai 整个 crate 零测试
- 前端: 138 个源文件仅 3 个测试文件(覆盖率 2.2%),API 层/Store 层/hooks 全部无测试
- E2E: Playwright 已配置(含 auth fixture),但零测试用例
1.2 目标
- 全量覆盖率: 后端所有层(service/handler/entity/dto)+ 前端所有层(API/Store/hooks/页面)达到 80%
- CI 增量门禁: 新增/修改文件覆盖率 ≥ 80% 才允许合并
- 时间线: 9 周分阶段完成
1.3 决策记录
| 决策 |
选择 |
理由 |
| 覆盖范围 |
全量 80% |
医疗场景需要全面质量保证 |
| CI 门禁 |
增量门禁 |
不阻塞现有开发,只要求新增代码 |
| 后端策略 |
集成测试为主(Testcontainers) |
最接近生产,SeaORM mock 不成熟 |
| 整体方案 |
分层渐进式(方案 A) |
按风险密度排序,与增量门禁配合 |
2. 后端测试策略
2.1 测试分层模型
2.2 TestDb 基础设施增强
当前 crates/erp-server/tests/integration/test_db.rs 已有 TestDb struct。需要增强为:
TestApp struct — 封装完整测试环境:
- TestDb(PostgreSQL Testcontainer + 自动迁移)
- Axum Router(与生产配置相同的路由)
- AppState(DatabaseConnection + EventBus + Crypto)
- HTTP 客户端(
reqwest::Client 或 tower::ServiceExt)
TestFixture 工厂 — 预构建测试数据:
create_tenant(name) → 创建租户 + 返回 TenantContext
create_user(tenant_id, role) → 创建用户 + 返回 JWT
create_patient(tenant_id, ...) → 创建患者档案
create_doctor(tenant_id, ...) → 创建医生档案
create_schedule(tenant_id, doctor_id, ...) → 创建排班
并行隔离 — 每个测试使用独立的 tenant_id,支持并行执行。
2.3 Phase 分配
Phase 1: 高风险 Service(Week 1-2)
| Service |
测试重点 |
估计测试数 |
points_service |
FIFO 积分消费、余额不足拒绝、并发消费安全性、签到积分 |
12 |
dialysis_service |
PII 字段加密存储、HMAC 索引查询、CRUD 完整性 |
8 |
alert_engine |
规则评估逻辑、cooldown 检查、危急值触发 |
8 |
alert_rule_service |
规则 CRUD、阈值验证、启用/禁用 |
6 |
device_reading_service |
批量插入、降采样聚合、数据范围查询 |
8 |
Phase 2: 中风险 Service(Week 3-4)
| Service |
测试重点 |
估计测试数 |
patient_service |
CRUD + 家属管理 + 标签管理 + 健康摘要 |
10 |
appointment_service |
创建预约 CAS + 状态变更 + 取消释放额度 |
8 |
follow_up_service |
状态机 6 种转换 + 任务分配 + 执行记录 |
8 |
consultation_service |
会话 CRUD + 消息收发 + 状态变更 |
5 |
doctor_service |
CRUD + 排班关联 |
4 |
| erp-ai 基础测试 |
提示模板 CRUD + 分析记录 + 使用统计 |
12 |
Phase 3: 低风险 Service + Handler + DTO(Week 5-6)
| Service |
测试重点 |
估计测试数 |
article_service |
CRUD + 审核状态流转 |
5 |
article_category_service |
CRUD + 层级管理 |
4 |
article_tag_service |
CRUD + 关联管理 |
3 |
offline_event_service |
CRUD + 报名管理 |
4 |
consent_service |
CRUD + 签署状态 |
3 |
diagnosis_service |
CRUD + ICD 编码验证 |
3 |
stats_service |
各维度统计查询正确性 |
5 |
health_data_service |
体征/化验/体检 CRUD + 趋势计算 |
8 |
| handler 层 |
16 个 handler 的 HTTP 层测试 |
16 |
| DTO 转换 |
请求/响应 DTO 序列化/反序列化 |
10 |
2.4 测试命名规范
2.5 测试文件组织
3. 前端测试策略
3.1 测试分层模型
3.2 测试工具链
| 工具 |
用途 |
状态 |
| Vitest |
单元测试 + 组件测试 |
✅ 已配置 |
| @testing-library/react |
组件渲染测试 |
✅ 已有 |
| MSW (mock-service-worker) |
API mock |
❌ 需新增 |
| Playwright |
E2E 测试 |
✅ 已配置 + auth fixture |
| @vitest/coverage-v8 |
覆盖率报告 |
❌ 需新增 |
3.3 MSW Mock 策略
建立 apps/web/src/test/ 目录:
3.4 Phase 4: 前端补测(Week 7-9)
Week 7: API 层 + Store 层
| 文件 |
测试重点 |
测试数 |
api/client.ts |
token 主动刷新、401 被动刷新、并发请求队列、缓存命中/过期 |
12 |
api/health/patients.ts |
CRUD 参数正确性、分页参数、错误映射 |
5 |
api/health/appointments.ts |
创建预约参数、状态变更、排班查询 |
4 |
api/health/*.ts(其余 5 个) |
CRUD 基础覆盖 |
10 |
stores/auth.ts |
login/logout/refresh 权限列表 |
5 |
stores/plugin.ts |
插件列表加载、菜单生成、去重 |
5 |
stores/health.ts |
名称缓存、批量解析 |
3 |
stores/message.ts |
SSE 连接、未读计数、乐观更新 |
4 |
Week 8: Hooks + 核心页面组件
| 文件 |
测试重点 |
测试数 |
hooks/useApiRequest.ts |
loading/error 状态、重试、取消 |
5 |
hooks/usePaginatedData.ts |
分页加载、刷新、参数变更 |
4 |
hooks/usePermission.ts |
权限检查、admin 跳过 |
3 |
pages/health/PatientList.tsx |
列表渲染、搜索、新建弹窗 |
5 |
pages/health/AppointmentList.tsx |
列表渲染、新建预约、状态变更 |
5 |
pages/health/ConsultationList.tsx |
列表渲染、行点击导航 |
3 |
pages/health/FollowUpTaskList.tsx |
列表渲染、状态筛选 |
3 |
pages/health/StatisticsDashboard.tsx |
数据加载、卡片渲染 |
3 |
Week 9: Playwright E2E
| 测试场景 |
覆盖流程 |
| 患者管理 CRUD |
登录 → 创建患者 → 编辑 → 查看 → 搜索 |
| 预约流程 |
选医生 → 查排班 → 创建预约 → 取消预约 |
| 随访任务 |
创建随访 → 分配 → 执行 → 完成 |
| 咨询流程 |
创建咨询 → 发送消息 → 关闭 |
| 数据统计 |
查看统计仪表板 → 导出 |
4. CI 门禁策略
4.1 增量覆盖率门禁
后端 — 使用 cargo-llvm-cov:
前端 — 使用 @vitest/coverage-v8:
4.2 CI 流水线
4.3 里程碑
| 时间点 |
门禁要求 |
| Week 6 后 |
后端增量门禁上线 |
| Week 9 后 |
前端增量门禁上线 |
| Week 12 后 |
全量覆盖率报告 + 目标复盘 |
5. 风险与缓解
| 风险 |
影响 |
缓解措施 |
| Testcontainers Windows 启动慢 |
开发体验差 |
CI 用 Linux runner;本地开发串行测试;预热 Docker 镜像 |
| MSW mock 与真实 API 不一致 |
测试通过但生产出错 |
关键流程 E2E 兜底;从 OpenAPI spec 生成 handlers |
| 补测与功能开发冲突 |
merge conflict |
测试文件独立于业务代码;集成测试集中在 erp-server/tests/ |
| 前端 9 周达不到 80% |
延期 |
接受"后端 80% + 前端 60%"作为 Phase 1 目标 |
| erp-ai 依赖外部 AI API |
测试不稳定 |
mock 外部 AI 调用,仅测试内部逻辑 |
6. 成功指标
| 指标 |
Week 6 目标 |
Week 9 目标 |
| 后端 service 测试覆盖率 |
≥ 80% |
≥ 85% |
| 后端全量测试覆盖率 |
≥ 70% |
≥ 80% |
| 前端 API+Store 测试覆盖率 |
- |
≥ 80% |
| 前端全量测试覆盖率 |
- |
≥ 60% |
| E2E 测试用例数 |
- |
≥ 5 |
| CI 增量门禁 |
后端上线 |
前后端上线 |