docs: 修正测试策略 spec 的事实性错误
修正 spec review 发现的问题: - C-1: TestDb 实际是本地 PostgreSQL 隔离,非 Testcontainers - C-2: E2E 已有 4 spec/10 测试,非零测试 - 补充 6 个遗漏的 service(alert/daily_monitoring/critical_value_threshold 等) - 增加 Phase 0 基础设施搭建 - 修正 CI 配置(增加 PostgreSQL service、验证链) - 补充 5 个遗漏风险项和回退策略 - 统一"全量 80%"目标的准确含义
This commit is contained in:
@@ -8,9 +8,9 @@
|
||||
|
||||
HMS 健康管理平台当前测试覆盖极低:
|
||||
|
||||
- **后端**: 461 单元测试 + 54 集成测试,但 erp-health 34 entity 中 27 个 service 零单元测试,erp-ai 整个 crate 零测试
|
||||
- **前端**: 138 个源文件仅 3 个测试文件(覆盖率 2.2%),API 层/Store 层/hooks 全部无测试
|
||||
- **E2E**: Playwright 已配置(含 auth fixture),但零测试用例
|
||||
- **后端**: 约 461 单元测试 + 54 集成测试(注:wiki/testing.md 记录 93 个,差距因统计口径不同 — 此处含所有 crate 的 `#[test]`/`#[tokio::test]` 标记),但 erp-health 34 entity 中 27 个 service 零单元测试,erp-ai 整个 crate 零测试
|
||||
- **前端**: 138 个源文件仅 3 个单元测试文件(覆盖率 2.2%),API 层/Store 层/hooks 全部无测试
|
||||
- **E2E**: Playwright 已配置(含 auth fixture `apps/web/e2e/auth.fixture.ts`),已有 4 个 spec、10 个测试用例(login/users/plugins/tenant-isolation),但健康模块零 E2E 覆盖
|
||||
|
||||
### 1.2 目标
|
||||
|
||||
@@ -24,7 +24,7 @@ HMS 健康管理平台当前测试覆盖极低:
|
||||
|------|------|------|
|
||||
| 覆盖范围 | 全量 80% | 医疗场景需要全面质量保证 |
|
||||
| CI 门禁 | 增量门禁 | 不阻塞现有开发,只要求新增代码 |
|
||||
| 后端策略 | 集成测试为主(Testcontainers) | 最接近生产,SeaORM mock 不成熟 |
|
||||
| 后端策略 | 集成测试为主(本地 PostgreSQL 隔离数据库) | 最接近生产,SeaORM mock 不成熟;当前 TestDb 已连接本地 PostgreSQL |
|
||||
| 整体方案 | 分层渐进式(方案 A) | 按风险密度排序,与增量门禁配合 |
|
||||
|
||||
---
|
||||
@@ -35,7 +35,7 @@ HMS 健康管理平台当前测试覆盖极低:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Integration Tests (Testcontainers) │ ← 27 service + 16 handler
|
||||
│ Integration Tests (本地 PG 隔离) │ ← 30 service + 16 handler
|
||||
│ erp-server/tests/integration/ │
|
||||
├─────────────────────────────────────────┤
|
||||
│ Unit Tests (tokio::test / #[test]) │ ← validation/crypto/masking
|
||||
@@ -48,13 +48,13 @@ HMS 健康管理平台当前测试覆盖极低:
|
||||
|
||||
### 2.2 TestDb 基础设施增强
|
||||
|
||||
当前 `crates/erp-server/tests/integration/test_db.rs` 已有 `TestDb` struct。需要增强为:
|
||||
当前 `crates/erp-server/tests/integration/test_db.rs` 已有 `TestDb` struct,连接**本地 PostgreSQL** 创建临时数据库(不依赖 Docker/Testcontainers,与开发环境一致)。需要增强为:
|
||||
|
||||
**TestApp struct** — 封装完整测试环境:
|
||||
- TestDb(PostgreSQL Testcontainer + 自动迁移)
|
||||
- Axum Router(与生产配置相同的路由)
|
||||
- AppState(DatabaseConnection + EventBus + Crypto)
|
||||
- HTTP 客户端(`reqwest::Client` 或 `tower::ServiceExt`)
|
||||
- TestDb(本地 PostgreSQL 隔离数据库 + 自动迁移)
|
||||
- Axum Router(仅注册 erp-health 模块,减少启动开销)
|
||||
- AppState(DatabaseConnection + EventBus + Crypto,使用测试专用密钥)
|
||||
- HTTP 客户端(使用 `tower::ServiceExt`,无需真实 TCP 监听,测试更快速稳定)
|
||||
|
||||
**TestFixture 工厂** — 预构建测试数据:
|
||||
- `create_tenant(name)` → 创建租户 + 返回 TenantContext
|
||||
@@ -67,6 +67,16 @@ HMS 健康管理平台当前测试覆盖极低:
|
||||
|
||||
### 2.3 Phase 分配
|
||||
|
||||
#### Phase 0: 测试基础设施搭建(Week 1 前 2 天)
|
||||
|
||||
| 任务 | 产出 |
|
||||
|------|------|
|
||||
| TestApp struct 实现 | TestDb + Axum Router + AppState + tower ServiceExt 客户端 |
|
||||
| TestFixture 工厂 | create_tenant/create_user/create_patient/create_doctor 工厂函数 |
|
||||
| `@vitest/coverage-v8` 安装配置 | 前端覆盖率报告可用 |
|
||||
| MSW v2 初始配置 | handlers.ts + server.ts 基础框架 |
|
||||
| `cargo-llvm-cov` 安装验证 | 后端增量覆盖率命令可用(配合自定义 git diff 脚本过滤) |
|
||||
|
||||
#### Phase 1: 高风险 Service(Week 1-2)
|
||||
|
||||
| Service | 测试重点 | 估计测试数 |
|
||||
@@ -75,6 +85,7 @@ HMS 健康管理平台当前测试覆盖极低:
|
||||
| `dialysis_service` | PII 字段加密存储、HMAC 索引查询、CRUD 完整性 | 8 |
|
||||
| `alert_engine` | 规则评估逻辑、cooldown 检查、危急值触发 | 8 |
|
||||
| `alert_rule_service` | 规则 CRUD、阈值验证、启用/禁用 | 6 |
|
||||
| `alert_service` | 告警 CRUD、状态变更、批量确认 | 5 |
|
||||
| `device_reading_service` | 批量插入、降采样聚合、数据范围查询 | 8 |
|
||||
|
||||
#### Phase 2: 中风险 Service(Week 3-4)
|
||||
@@ -98,11 +109,17 @@ HMS 健康管理平台当前测试覆盖极低:
|
||||
| `offline_event_service` | CRUD + 报名管理 | 4 |
|
||||
| `consent_service` | CRUD + 签署状态 | 3 |
|
||||
| `diagnosis_service` | CRUD + ICD 编码验证 | 3 |
|
||||
| `daily_monitoring_service` | 日常监测 CRUD + 阈值校验 | 4 |
|
||||
| `critical_value_threshold_service` | 阈值 CRUD + 范围校验 | 3 |
|
||||
| `stats_service` | 各维度统计查询正确性 | 5 |
|
||||
| `health_data_service` | 体征/化验/体检 CRUD + 趋势计算 | 8 |
|
||||
| `trend_service` | 已有 14 个内联测试,补充集成测试 | 3 |
|
||||
| `masking` | 已有 14 个内联测试,保持 | 0 |
|
||||
| handler 层 | 16 个 handler 的 HTTP 层测试 | 16 |
|
||||
| DTO 转换 | 请求/响应 DTO 序列化/反序列化 | 10 |
|
||||
|
||||
> 注:所有健康模块集成测试集中在 `erp-server/tests/integration/` 下,通过 `cargo test -p erp-server` 运行。erp-health 的内联单元测试(validation/crypto/masking/trend)通过 `cargo test -p erp-health` 运行。
|
||||
|
||||
### 2.4 测试命名规范
|
||||
|
||||
```
|
||||
@@ -220,7 +237,9 @@ apps/web/src/test/
|
||||
| `pages/health/FollowUpTaskList.tsx` | 列表渲染、状态筛选 | 3 |
|
||||
| `pages/health/StatisticsDashboard.tsx` | 数据加载、卡片渲染 | 3 |
|
||||
|
||||
#### Week 9: Playwright E2E
|
||||
#### Week 9: Playwright E2E(健康模块专项)
|
||||
|
||||
已有 4 个基础 ERP spec(login/users/plugins/tenant-isolation,10 个测试)。Week 9 新增健康模块 E2E:
|
||||
|
||||
| 测试场景 | 覆盖流程 |
|
||||
|---------|---------|
|
||||
@@ -230,47 +249,83 @@ apps/web/src/test/
|
||||
| 咨询流程 | 创建咨询 → 发送消息 → 关闭 |
|
||||
| 数据统计 | 查看统计仪表板 → 导出 |
|
||||
|
||||
> 注:E2E 测试依赖前后端同时启动。Playwright 配置了 `webServer.command: pnpm dev`(前端),但需确保后端服务已运行。在 CI 中需同时启动后端(`cargo run`)+ 前端(`pnpm dev`)。
|
||||
|
||||
---
|
||||
|
||||
## 4. CI 门禁策略
|
||||
|
||||
### 4.1 增量覆盖率门禁
|
||||
|
||||
**后端** — 使用 `cargo-llvm-cov`:
|
||||
**后端** — 使用 `cargo-llvm-cov` 配合自定义脚本:
|
||||
```bash
|
||||
cargo llvm-cov --fail-under-lines=80 --modified-files-only
|
||||
# 安装: cargo install cargo-llvm-cov
|
||||
# 全量测试
|
||||
cargo llvm-cov --workspace --lcov --output-path lcov.info
|
||||
# 增量检查(自定义脚本,基于 git diff 过滤变更文件)
|
||||
cargo llvm-cov --workspace --json | python3 scripts/coverage-diff-check.py --threshold=80
|
||||
```
|
||||
|
||||
> 注:`cargo-llvm-cov` 原生不支持 `--modified-files-only`,需要自定义脚本实现增量过滤。Phase 0 中需验证可行性。
|
||||
|
||||
**前端** — 使用 `@vitest/coverage-v8`:
|
||||
```bash
|
||||
cd apps/web && pnpm vitest run --coverage --changed=HEAD~1
|
||||
cd apps/web && pnpm vitest run --coverage
|
||||
# 增量检查通过自定义脚本过滤变更文件
|
||||
```
|
||||
|
||||
### 4.2 CI 流水线
|
||||
|
||||
> **前置条件**: 项目当前无 CI 配置(`.github/workflows/` 不存在),Phase 0 需创建初始 workflow。
|
||||
|
||||
```yaml
|
||||
# PR 提交时
|
||||
# .github/workflows/test.yml
|
||||
on: pull_request
|
||||
jobs:
|
||||
backend-test:
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: test_password
|
||||
POSTGRES_DB: erp_test
|
||||
ports: ["5432:5432"]
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
env:
|
||||
ERP__DATABASE__URL: postgres://postgres:test_password@localhost:5432/erp_test
|
||||
ERP__JWT__SECRET: ci-test-jwt-secret
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- cargo test --workspace
|
||||
- cargo llvm-cov --fail-under-lines=80 --modified-files-only
|
||||
- cargo llvm-cov --workspace --json
|
||||
|
||||
frontend-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- cd apps/web && pnpm test:ci
|
||||
- pnpm vitest run --coverage --changed=origin/main
|
||||
- uses: actions/checkout@v4
|
||||
- cd apps/web && pnpm install && pnpm test:ci
|
||||
|
||||
# E2E: 仅 main 分支或手动触发
|
||||
e2e-test:
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
postgres: # 同上
|
||||
steps:
|
||||
- cargo run & # 后台启动后端
|
||||
- cd apps/web && pnpm dev & # 后台启动前端
|
||||
- sleep 10 # 等待服务就绪
|
||||
- pnpm exec playwright test
|
||||
```
|
||||
|
||||
> CI 流水线需包含 CLAUDE.md 要求的完整验证链:`cargo check` → `cargo test` → `cargo clippy` → `pnpm build`。
|
||||
|
||||
### 4.3 里程碑
|
||||
|
||||
| 时间点 | 门禁要求 |
|
||||
@@ -285,11 +340,16 @@ jobs:
|
||||
|
||||
| 风险 | 影响 | 缓解措施 |
|
||||
|------|------|---------|
|
||||
| Testcontainers Windows 启动慢 | 开发体验差 | CI 用 Linux runner;本地开发串行测试;预热 Docker 镜像 |
|
||||
| MSW mock 与真实 API 不一致 | 测试通过但生产出错 | 关键流程 E2E 兜底;从 OpenAPI spec 生成 handlers |
|
||||
| 本地 PG 并行测试连接池耗尽 | 多个 TestDb 实例同时创建可能超限 | 限制并行度 `--test-threads=2`;CI 环境单独配置 |
|
||||
| 测试 panic 后残留临时数据库 | 长期累积占用磁盘 | TestApp Drop 时强制清理;定期脚本清理 `test_*` 前缀数据库 |
|
||||
| 并行迁移竞争 | 多个 TestDb 同时 `Migrator::up` | 每个测试用独立数据库名(UUID),互不影响 |
|
||||
| MSW mock 与真实 API 不一致 | 测试通过但生产出错 | 关键流程 E2E 兜底;MSW handlers 从 OpenAPI spec 自动生成 |
|
||||
| 补测与功能开发冲突 | merge conflict | 测试文件独立于业务代码;集成测试集中在 erp-server/tests/ |
|
||||
| 前端 9 周达不到 80% | 延期 | 接受"后端 80% + 前端 60%"作为 Phase 1 目标 |
|
||||
| 前端 9 周达不到 80% | 延期 | 接受"后端 80% + 前端 60%"作为 Phase 1 目标,前端在后续迭代持续补齐 |
|
||||
| erp-ai 依赖外部 AI API | 测试不稳定 | mock 外部 AI 调用,仅测试内部逻辑 |
|
||||
| MSW 与 axios 缓存 adapter 冲突 | mock 拦截异常 | MSW 在 service worker 层拦截,绕过 axios adapter;需验证兼容性 |
|
||||
| E2E 测试后端未启动失败 | 测试环境不可用 | CI 中先启动后端再运行 E2E;本地用 dev.ps1 一键启动 |
|
||||
| 目标不可达时无回退方案 | 计划失控 | 每 Phase 结束复盘覆盖率;如 Phase 2 后仅 50%,则缩减 Phase 3 范围或延长时间线 |
|
||||
|
||||
---
|
||||
|
||||
@@ -300,6 +360,8 @@ jobs:
|
||||
| 后端 service 测试覆盖率 | ≥ 80% | ≥ 85% |
|
||||
| 后端全量测试覆盖率 | ≥ 70% | ≥ 80% |
|
||||
| 前端 API+Store 测试覆盖率 | - | ≥ 80% |
|
||||
| 前端全量测试覆盖率 | - | ≥ 60% |
|
||||
| E2E 测试用例数 | - | ≥ 5 |
|
||||
| 前端全量测试覆盖率 | - | ≥ 60%(Phase 1 目标,后续迭代持续提升到 80%) |
|
||||
| E2E 测试用例数(健康模块) | - | ≥ 5 个新 spec |
|
||||
| CI 增量门禁 | 后端上线 | 前后端上线 |
|
||||
|
||||
> **目标澄清**: "全量 80%"是最终目标。Phase 1(9 周)的目标是后端 80% + 前端 60%,前端剩余部分在后续迭代中持续补齐。每 Phase 结束后复盘实际覆盖率,必要时调整计划。
|
||||
|
||||
Reference in New Issue
Block a user