From 8cd65f7be514403c7dddf974a2f4e56eadb7a708 Mon Sep 17 00:00:00 2001 From: iven Date: Mon, 27 Apr 2026 00:13:39 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B5=8B=E8=AF=95=E8=A6=86=E7=9B=96?= =?UTF-8?q?=E7=8E=87=E6=8F=90=E5=8D=87=E7=AD=96=E7=95=A5=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E8=A7=84=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主题 1 头脑风暴产出 — 测试覆盖率从 2% 提升到 80% 的分阶段路线图, 覆盖后端 27 个无测试 service、erp-ai 零测试、前端 138 文件仅 3 个测试。 采用分层渐进式方案,9 周分 4 Phase 完成。 --- ...026-04-26-test-coverage-strategy-design.md | 305 ++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-26-test-coverage-strategy-design.md diff --git a/docs/superpowers/specs/2026-04-26-test-coverage-strategy-design.md b/docs/superpowers/specs/2026-04-26-test-coverage-strategy-design.md new file mode 100644 index 0000000..f460a8a --- /dev/null +++ b/docs/superpowers/specs/2026-04-26-test-coverage-strategy-design.md @@ -0,0 +1,305 @@ +# 测试覆盖率提升策略设计规格 + +> 日期: 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 测试分层模型 + +``` +┌─────────────────────────────────────────┐ +│ Integration Tests (Testcontainers) │ ← 27 service + 16 handler +│ erp-server/tests/integration/ │ +├─────────────────────────────────────────┤ +│ Unit Tests (tokio::test / #[test]) │ ← validation/crypto/masking +│ 内联 #[cfg(test)] mod tests │ +├─────────────────────────────────────────┤ +│ Pure Function Tests │ ← DTO 转换、枚举、工具函数 +│ 零依赖,毫秒级 │ +└─────────────────────────────────────────┘ +``` + +### 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 测试命名规范 + +``` +test_{功能}_{场景}_{预期结果} + +例: test_points_consume_fifo_balance_deducted + test_patient_create_duplicate_id_card_returns_conflict + test_appointment_create_exceeds_max_returns_error + test_alert_engine_cooldown_prevents_duplicate + test_dialysis_create_pii_fields_encrypted +``` + +### 2.5 测试文件组织 + +``` +crates/erp-server/tests/integration/ +├── test_db.rs # TestDb + TestApp 基础设施 +├── test_fixture.rs # TestFixture 工厂 +├── auth_tests.rs # 已有 +├── workflow_tests.rs # 已有 +├── health_patient_tests.rs # 已有(扩展) +├── health_pii_encryption_tests.rs # 已有(保持) +├── health_appointment_tests.rs # 已有(扩展) +├── health_points_tests.rs # 新增 +├── health_dialysis_tests.rs # 新增 +├── health_alert_tests.rs # 新增 +├── health_device_reading_tests.rs # 新增 +├── health_follow_up_tests.rs # 新增 +├── health_consultation_tests.rs # 新增 +├── health_doctor_tests.rs # 新增 +├── health_article_tests.rs # 新增 +├── health_stats_tests.rs # 新增 +├── health_data_tests.rs # 新增 +├── ai_prompt_template_tests.rs # 新增 +├── ai_analysis_tests.rs # 新增 +└── ai_usage_tests.rs # 新增 +``` + +--- + +## 3. 前端测试策略 + +### 3.1 测试分层模型 + +``` +┌─────────────────────────────────────────┐ +│ E2E Tests (Playwright) │ ← 5 个关键用户流程 +├─────────────────────────────────────────┤ +│ Page Integration Tests │ ← 8 个核心页面 +│ vitest + @testing-library/react │ +├─────────────────────────────────────────┤ +│ Store/Hook Unit Tests │ ← 5 stores + 3 hooks +│ vitest │ +├─────────────────────────────────────────┤ +│ API Layer Tests │ ← client.ts + 7 health API +│ vitest + MSW │ +└─────────────────────────────────────────┘ +``` + +### 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/` 目录: + +``` +apps/web/src/test/ +├── setup.ts # 测试全局 setup(已有,需增强) +├── mocks/ +│ ├── handlers.ts # 统一 API mock handlers +│ ├── server.ts # MSW server setup +│ ├── browser.ts # MSW browser setup(E2E 用) +│ └── fixtures/ # 测试数据 JSON +│ ├── patients.json +│ ├── appointments.json +│ └── ... +└── utils/ + ├── render-with-providers.tsx # 包含 Router + Store 的 render wrapper + └── wait-for.ts # 异步等待工具 +``` + +### 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`: +```bash +cargo llvm-cov --fail-under-lines=80 --modified-files-only +``` + +**前端** — 使用 `@vitest/coverage-v8`: +```bash +cd apps/web && pnpm vitest run --coverage --changed=HEAD~1 +``` + +### 4.2 CI 流水线 + +```yaml +# PR 提交时 +on: pull_request +jobs: + backend-test: + runs-on: ubuntu-latest + steps: + - cargo test --workspace + - cargo llvm-cov --fail-under-lines=80 --modified-files-only + + frontend-test: + runs-on: ubuntu-latest + steps: + - cd apps/web && pnpm test:ci + - pnpm vitest run --coverage --changed=origin/main + + # E2E: 仅 main 分支或手动触发 + e2e-test: + if: github.ref == 'refs/heads/main' + steps: + - pnpm exec playwright test +``` + +### 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 增量门禁 | 后端上线 | 前后端上线 |