docs: 测试覆盖率提升实施计划
基于 spec 的 5 Phase + CI 门禁实施计划: - Phase 0: TestApp + TestFixture + MSW + 覆盖率工具 + CI(2天) - Phase 1: 高风险 service 测试 — points/dialysis/alert/device_reading(Week 1-2) - Phase 2: 中风险 service 测试 — patient/appointment/follow_up/consultation/doctor/ai(Week 3-4) - Phase 3: 低风险 service + handler + DTO + 后端增量门禁(Week 5-6) - Phase 4: 前端补测 — API/Store/hooks/pages/E2E(Week 7-9) 共 43 个 Task,预计新增 ~230 个测试用例
This commit is contained in:
544
docs/superpowers/plans/2026-04-26-test-coverage-strategy.md
Normal file
544
docs/superpowers/plans/2026-04-26-test-coverage-strategy.md
Normal file
@@ -0,0 +1,544 @@
|
||||
# 测试覆盖率提升实施计划
|
||||
|
||||
> 设计规格: `docs/superpowers/specs/2026-04-26-test-coverage-strategy-design.md`
|
||||
> 日期: 2026-04-26 | 状态: draft | 总周期: 9 周(+ Phase 0: 2 天)
|
||||
|
||||
---
|
||||
|
||||
## Phase 0: 测试基础设施搭建(2 天)
|
||||
|
||||
### Task 1: TestApp struct 实现
|
||||
|
||||
**目标**: 在现有 `TestDb` 基础上封装 `TestApp`,提供完整测试环境。
|
||||
|
||||
**涉及文件**:
|
||||
- 修改: `crates/erp-server/tests/integration/test_db.rs`
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. 在 `test_db.rs` 中新增 `TestApp` struct:
|
||||
```rust
|
||||
pub struct TestApp {
|
||||
test_db: TestDb,
|
||||
health_state: HealthState,
|
||||
tenant_id: Uuid,
|
||||
operator_id: Uuid,
|
||||
}
|
||||
```
|
||||
|
||||
2. 实现 `TestApp::new()`:
|
||||
- 调用 `TestDb::new()` 创建隔离数据库
|
||||
- 构建 `HealthState { db, event_bus: EventBus::new(100), crypto: PiiCrypto::dev_default() }`
|
||||
- 生成随机 `tenant_id` 和 `operator_id`
|
||||
- 复用现有 `make_state` 模式(见 `health_patient_tests.rs:15-21`)
|
||||
|
||||
3. 添加访问方法:
|
||||
- `db()` → `&DatabaseConnection`
|
||||
- `health_state()` → `&HealthState`
|
||||
- `tenant_id()` → `Uuid`
|
||||
- `operator_id()` → `Uuid`
|
||||
|
||||
**验收标准**:
|
||||
- `cargo test -p erp-server test_app_new` 通过
|
||||
- TestApp Drop 时自动清理临时数据库(复用 TestDb 的 Drop 实现)
|
||||
- 现有 7 个集成测试不受影响
|
||||
|
||||
---
|
||||
|
||||
### Task 2: TestFixture 工厂函数
|
||||
|
||||
**目标**: 提供预构建测试数据的工厂函数,减少每个测试的 setup 代码。
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-server/tests/integration/test_fixture.rs`
|
||||
- 修改: `crates/erp-server/tests/integration.rs`(添加模块注册)
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. 创建 `TestFixture` 模块,实现以下工厂函数:
|
||||
|
||||
```rust
|
||||
impl TestApp {
|
||||
/// 创建患者(含基本字段,可自定义覆盖)
|
||||
pub async fn create_patient(&self, overrides: PatientOverrides) -> Patient { ... }
|
||||
|
||||
/// 创建医生
|
||||
pub async fn create_doctor(&self, overrides: DoctorOverrides) -> DoctorProfile { ... }
|
||||
|
||||
/// 创建排班
|
||||
pub async fn create_schedule(&self, doctor_id: Uuid, date: NaiveDate, ...) -> DoctorSchedule { ... }
|
||||
|
||||
/// 创建随访任务
|
||||
pub async fn create_follow_up_task(&self, patient_id: Uuid, ...) -> FollowUpTask { ... }
|
||||
|
||||
/// 创建积分账户 + 初始积分
|
||||
pub async fn create_points_account(&self, patient_id: Uuid, initial_balance: i32) -> PointsAccount { ... }
|
||||
}
|
||||
```
|
||||
|
||||
2. 使用 `Default` trait + 覆盖模式:
|
||||
```rust
|
||||
#[derive(Default)]
|
||||
pub struct PatientOverrides {
|
||||
pub name: Option<String>,
|
||||
pub gender: Option<String>,
|
||||
pub birth_date: Option<NaiveDate>,
|
||||
pub id_number: Option<String>,
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- 现有 `health_patient_tests.rs` 可用 fixture 重写(验证工厂函数可用)
|
||||
- 每个工厂函数 ≤ 30 行代码
|
||||
- 创建的数据包含正确的 `tenant_id` 和 `created_by`
|
||||
|
||||
---
|
||||
|
||||
### Task 3: 前端 MSW v2 初始配置
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `apps/web/src/test/mocks/handlers.ts`
|
||||
- 新增: `apps/web/src/test/mocks/server.ts`
|
||||
- 修改: `apps/web/src/test/setup.ts`
|
||||
- 修改: `apps/web/package.json`(添加 `msw` 依赖)
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. 安装 MSW v2: `pnpm add -D msw`
|
||||
2. 创建 `handlers.ts` — 初始仅包含 auth 基础 handler(登录/刷新):
|
||||
```typescript
|
||||
export const handlers = [
|
||||
http.post('/api/v1/auth/login', () => HttpResponse.json({ ... })),
|
||||
http.post('/api/v1/auth/refresh', () => HttpResponse.json({ ... })),
|
||||
]
|
||||
```
|
||||
3. 创建 `server.ts`:
|
||||
```typescript
|
||||
import { setupServer } from 'msw/node'
|
||||
export const server = setupServer(...handlers)
|
||||
```
|
||||
4. 在 `setup.ts` 中启动/清理 MSW server:
|
||||
```typescript
|
||||
beforeAll(() => server.listen({ onUnhandledRequest: 'warn' }))
|
||||
afterEach(() => server.resetHandlers())
|
||||
afterAll(() => server.close())
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- `pnpm test` 无报错
|
||||
- MSW server 正确拦截匹配的请求
|
||||
- 未匹配的请求产生 warning(不是 error)
|
||||
|
||||
---
|
||||
|
||||
### Task 4: 前端覆盖率工具配置
|
||||
|
||||
**涉及文件**:
|
||||
- 修改: `apps/web/package.json`
|
||||
- 修改: `apps/web/vitest.config.ts`
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. 安装: `pnpm add -D @vitest/coverage-v8`
|
||||
2. 在 `vitest.config.ts` 添加 coverage 配置:
|
||||
```typescript
|
||||
test: {
|
||||
coverage: {
|
||||
provider: 'v8',
|
||||
reporter: ['text', 'lcov'],
|
||||
include: ['src/**/*.{ts,tsx}'],
|
||||
exclude: ['src/test/**', 'src/**/*.test.*', 'src/**/*.d.ts'],
|
||||
},
|
||||
}
|
||||
```
|
||||
3. 添加 npm script: `"test:coverage": "vitest run --coverage"`
|
||||
|
||||
**验收标准**:
|
||||
- `pnpm test:coverage` 生成覆盖率报告
|
||||
- 输出包含各文件的行覆盖率百分比
|
||||
|
||||
---
|
||||
|
||||
### Task 5: 后端覆盖率工具安装验证
|
||||
|
||||
**涉及文件**: 无代码变更,仅环境安装
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. 安装 `cargo-llvm-cov`: `cargo install cargo-llvm-cov`
|
||||
2. 验证基本功能: `cargo llvm-cov --workspace --text`
|
||||
3. 编写增量检查脚本 `scripts/coverage-diff-check.py`(或 shell):
|
||||
- 读取 `cargo llvm-cov --json` 输出
|
||||
- 通过 `git diff --name-only origin/main` 获取变更文件列表
|
||||
- 过滤出变更文件的覆盖率
|
||||
- 低于 80% 的文件列表退出码 1
|
||||
|
||||
**验收标准**:
|
||||
- `cargo llvm-cov --workspace --text` 输出覆盖率报告
|
||||
- 增量检查脚本对模拟变更文件正确判断通过/不通过
|
||||
|
||||
---
|
||||
|
||||
### Task 6: CI workflow 初始创建
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `.github/workflows/test.yml`
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. 创建基础 CI workflow,包含:
|
||||
- `backend-test` job: `cargo check` → `cargo test` → `cargo clippy`
|
||||
- `frontend-test` job: `pnpm install` → `pnpm test:ci` → `pnpm build`
|
||||
- PostgreSQL service 容器(仅 backend-test)
|
||||
- 环境变量配置(测试用 JWT secret、数据库 URL)
|
||||
|
||||
2. 配置触发条件: `on: pull_request` + `on: push: main`
|
||||
|
||||
**验收标准**:
|
||||
- Workflow 文件语法正确(`actionlint` 验证)
|
||||
- 包含 spec 要求的完整验证链: check → test → clippy → build
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: 高风险 Service 测试(Week 1-2)
|
||||
|
||||
> 共 6 个 service,约 47 个测试。所有测试使用 TestApp + TestFixture 模式。
|
||||
|
||||
### Task 7: points_service 测试(12 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-server/tests/integration/health_points_tests.rs`
|
||||
- 修改: `crates/erp-server/tests/integration.rs`
|
||||
|
||||
**测试用例清单**:
|
||||
|
||||
| 测试名 | 场景 |
|
||||
|--------|------|
|
||||
| `test_points_earn_sign_in` | 签到积分 — 首次签到成功,重复签到同天拒绝 |
|
||||
| `test_points_earn_custom` | 自定义积分增加 |
|
||||
| `test_points_consume_fifo_deduction` | FIFO 消费 — 先消耗最早的积分记录 |
|
||||
| `test_points_consume_balance_insufficient` | 余额不足时返回错误 |
|
||||
| `test_points_consume_exact_balance` | 消费金额等于余额 |
|
||||
| `test_points_consume_partial` | 消费金额小于单条记录,正确拆分 |
|
||||
| `test_points_account_create_on_first_earn` | 首次获取积分时自动创建账户 |
|
||||
| `test_points_checkin_streak` | 连续签到奖励 |
|
||||
| `test_points_order_create` | 积分兑换商品 — 创建订单 |
|
||||
| `test_points_order_insufficient_cancel` | 积分不足时订单失败 |
|
||||
| `test_points_transaction_history` | 交易记录查询 |
|
||||
| `test_points_tenant_isolation` | 租户隔离 — A 的积分 B 看不到 |
|
||||
|
||||
**验收标准**:
|
||||
- `cargo test -p erp-server health_points` 全部通过
|
||||
- FIFO 消费逻辑有明确的事务性验证(回滚场景)
|
||||
|
||||
---
|
||||
|
||||
### Task 8: dialysis_service 测试(8 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-server/tests/integration/health_dialysis_tests.rs`
|
||||
|
||||
**测试用例清单**:
|
||||
|
||||
| 测试名 | 场景 |
|
||||
|--------|------|
|
||||
| `test_dialysis_create_basic` | 创建透析记录基本 CRUD |
|
||||
| `test_dialysis_create_pii_encrypted` | PII 字段(病史、并发症)加密存储 |
|
||||
| `test_dialysis_update_status_flow` | 状态流转: scheduled → in_progress → completed |
|
||||
| `test_dialysis_list_by_patient` | 按患者 ID 过滤列表 |
|
||||
| `test_dialysis_tenant_isolation` | 租户隔离 |
|
||||
| `test_dialysis_version_conflict` | 乐观锁 — 旧版本更新拒绝 |
|
||||
| `test_dialysis_soft_delete` | 软删除后不可见 |
|
||||
| `test_dialysis_create_without_patient_returns_error` | 无效患者 ID 返回错误 |
|
||||
|
||||
**验收标准**:
|
||||
- `cargo test -p erp-server health_dialysis` 全部通过
|
||||
- PII 加密字段在数据库层面不可明文读取(验证密文格式)
|
||||
|
||||
---
|
||||
|
||||
### Task 9: alert_engine 测试(8 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-server/tests/integration/health_alert_tests.rs`(包含 engine + rule + service 测试)
|
||||
|
||||
**测试用例清单**:
|
||||
|
||||
| 测试名 | 场景 |
|
||||
|--------|------|
|
||||
| `test_alert_engine_evaluate_threshold_exceeded` | 体征超阈值触发告警 |
|
||||
| `test_alert_engine_evaluate_threshold_normal` | 体征正常不触发 |
|
||||
| `test_alert_engine_cooldown_prevents_duplicate` | cooldown 期内不重复触发 |
|
||||
| `test_alert_engine_multiple_rules` | 多规则并行评估 |
|
||||
| `test_alert_rule_crud` | 规则 CRUD 完整性 |
|
||||
| `test_alert_rule_enable_disable` | 规则启用/禁用 |
|
||||
| `test_alert_acknowledge` | 告警确认状态变更 |
|
||||
| `test_alert_batch_acknowledge` | 批量确认 |
|
||||
|
||||
**验收标准**:
|
||||
- `cargo test -p erp-server health_alert` 全部通过
|
||||
- cooldown 逻辑精确到秒级验证
|
||||
|
||||
---
|
||||
|
||||
### Task 10: device_reading_service 测试(8 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-server/tests/integration/health_device_reading_tests.rs`
|
||||
|
||||
**测试用例清单**:
|
||||
|
||||
| 测试名 | 场景 |
|
||||
|--------|------|
|
||||
| `test_device_reading_batch_insert` | 批量插入(模拟 50 条数据) |
|
||||
| `test_device_reading_upsert_hourly` | 降采样聚合 — 同一小时的数据合并 |
|
||||
| `test_device_reading_query_range` | 时间范围查询 |
|
||||
| `test_device_reading_query_by_device_type` | 按设备类型过滤 |
|
||||
| `test_device_reading_tenant_isolation` | 租户隔离 |
|
||||
| `test_device_reading_invalid_data_rejected` | 无效数据(空值、超范围)拒绝 |
|
||||
| `test_device_reading_latest_by_patient` | 获取患者最新读数 |
|
||||
| `test_device_reading_sync_event_published` | 数据同步后事件发布 |
|
||||
|
||||
**验收标准**:
|
||||
- `cargo test -p erp-server health_device_reading` 全部通过
|
||||
- 降采样逻辑的聚合值(avg/min/max)精度正确
|
||||
|
||||
---
|
||||
|
||||
### Task 11: 扩展已有患者测试(+3 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 修改: `crates/erp-server/tests/integration/health_patient_tests.rs`
|
||||
|
||||
**新增测试**:
|
||||
|
||||
| 测试名 | 场景 |
|
||||
|--------|------|
|
||||
| `test_patient_update_version_conflict` | 乐观锁冲突 |
|
||||
| `test_patient_create_with_pii_encrypted` | PII 字段加密存储验证 |
|
||||
| `test_patient_search_by_name` | 按名称搜索 |
|
||||
|
||||
---
|
||||
|
||||
### Task 12: 扩展已有预约测试(+3 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 修改: `crates/erp-server/tests/integration/health_appointment_tests.rs`
|
||||
|
||||
**新增测试**:
|
||||
|
||||
| 测试名 | 场景 |
|
||||
|--------|------|
|
||||
| `test_appointment_cas_exceeds_max_returns_error` | 预约超额拒绝 |
|
||||
| `test_appointment_cancel_releases_slot` | 取消预约释放名额 |
|
||||
| `test_appointment_status_flow` | 状态完整流转 |
|
||||
|
||||
**Phase 1 验收**:
|
||||
- 所有新增测试通过: `cargo test -p erp-server`
|
||||
- 覆盖率提升约 20-25%(从当前基线)
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: 中风险 Service 测试(Week 3-4)
|
||||
|
||||
> 共 5 个 service + erp-ai,约 47 个测试。
|
||||
|
||||
### Task 13: patient_service 完整测试(10 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 修改: `crates/erp-server/tests/integration/health_patient_tests.rs`
|
||||
|
||||
**新增测试**: 家庭成员管理 CRUD(4)、标签管理 CRUD(3)、健康摘要(2)、搜索/过滤(1)
|
||||
|
||||
### Task 14: appointment_service 完整测试(8 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 修改: `crates/erp-server/tests/integration/health_appointment_tests.rs`
|
||||
|
||||
**新增测试**: 排班管理 CRUD(3)、预约时间冲突(1)、并发安全(2)、多租户隔离(2)
|
||||
|
||||
### Task 15: follow_up_service 测试(8 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-server/tests/integration/health_follow_up_tests.rs`
|
||||
|
||||
**新增测试**: 状态机 6 种转换(6)、任务分配(1)、执行记录(1)
|
||||
|
||||
### Task 16: consultation_service 测试(5 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-server/tests/integration/health_consultation_tests.rs`
|
||||
|
||||
**新增测试**: 会话 CRUD(3)、消息收发(1)、状态变更(1)
|
||||
|
||||
### Task 17: doctor_service 测试(4 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-server/tests/integration/health_doctor_tests.rs`
|
||||
|
||||
**新增测试**: CRUD(3)、排班关联(1)
|
||||
|
||||
### Task 18: erp-ai 基础测试(12 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-server/tests/integration/ai_prompt_template_tests.rs`
|
||||
- 新增: `crates/erp-server/tests/integration/ai_analysis_tests.rs`
|
||||
- 新增: `crates/erp-server/tests/integration/ai_usage_tests.rs`
|
||||
|
||||
**新增测试**: 提示模板 CRUD(4)、分析记录 CRUD(4)、使用统计(4)
|
||||
|
||||
**Phase 2 验收**:
|
||||
- `cargo test -p erp-server` 全部通过
|
||||
- 后端 service 层覆盖率 ≥ 55%
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: 低风险 Service + Handler + DTO(Week 5-6)
|
||||
|
||||
> 共 14 个测试文件,约 71 个测试。
|
||||
|
||||
### Task 19-28: 低风险 Service 测试
|
||||
|
||||
每个 service 一个测试文件,遵循统一模式(CRUD + 租户隔离 + 软删除 + 乐观锁):
|
||||
|
||||
| Task | Service | 文件 | 测试数 |
|
||||
|------|---------|------|--------|
|
||||
| 19 | article_service | health_article_tests.rs | 5 |
|
||||
| 20 | article_category_service | (合并入 Task 19) | 4 |
|
||||
| 21 | article_tag_service | (合并入 Task 19) | 3 |
|
||||
| 22 | offline_event_service | health_offline_event_tests.rs | 4 |
|
||||
| 23 | consent_service | health_consent_tests.rs | 3 |
|
||||
| 24 | diagnosis_service | health_diagnosis_tests.rs | 3 |
|
||||
| 25 | daily_monitoring_service | health_daily_monitoring_tests.rs | 4 |
|
||||
| 26 | critical_value_threshold_service | (合并入 Task 9 alert 测试文件) | 3 |
|
||||
| 27 | stats_service | health_stats_tests.rs | 5 |
|
||||
| 28 | health_data_service | health_data_tests.rs | 8 |
|
||||
|
||||
### Task 29: trend_service 集成测试补充(3 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-server/tests/integration/health_trend_tests.rs`
|
||||
|
||||
### Task 30: Handler 层 HTTP 测试(16 个)
|
||||
|
||||
**目标**: 验证 HTTP 层的权限检查、请求解析、响应格式。
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-server/tests/integration/health_handler_tests.rs`
|
||||
|
||||
**测试模式**: 使用 `tower::ServiceExt` 调用 Axum Router,验证 HTTP 状态码和响应体格式。
|
||||
|
||||
**覆盖**: 每个核心 handler 1 个测试(患者/预约/随访/咨询/医生/文章/积分/体征/告警/透析等 16 个 handler)
|
||||
|
||||
### Task 31: DTO 转换测试(10 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `crates/erp-health/src/dto/dto_tests.rs`(内联 `#[cfg(test)]`)
|
||||
|
||||
**测试内容**: 请求 DTO 反序列化(JSON → struct)+ 响应 DTO 序列化(struct → JSON)+ 边界值
|
||||
|
||||
### Task 32: CI 后端增量门禁上线
|
||||
|
||||
**涉及文件**:
|
||||
- 修改: `.github/workflows/test.yml`
|
||||
|
||||
**操作**: 在 backend-test job 中添加增量覆盖率检查步骤
|
||||
|
||||
**Phase 3 验收**:
|
||||
- 后端全量测试覆盖率 ≥ 70%
|
||||
- CI 增量门禁生效
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: 前端补测(Week 7-9)
|
||||
|
||||
### Task 33: API 层测试 — client.ts(12 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `apps/web/src/api/client.test.ts`
|
||||
|
||||
**测试内容**: token 主动刷新、401 被动刷新、并发请求队列去重、GET 缓存命中/过期、错误映射
|
||||
|
||||
**工具**: MSW mock `/api/v1/auth/refresh` 等端点
|
||||
|
||||
### Task 34: API 层测试 — health 模块(19 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `apps/web/src/api/health/patients.test.ts`
|
||||
- 新增: `apps/web/src/api/health/appointments.test.ts`
|
||||
- 新增: `apps/web/src/api/health/other.test.ts`
|
||||
|
||||
**测试内容**: 每个 API 文件的 CRUD 参数正确性、分页参数、错误映射
|
||||
|
||||
### Task 35: Store 层测试(17 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `apps/web/src/stores/auth.test.ts`
|
||||
- 新增: `apps/web/src/stores/plugin.test.ts`
|
||||
- 新增: `apps/web/src/stores/health.test.ts`
|
||||
- 新增: `apps/web/src/stores/message.test.ts`
|
||||
|
||||
### Task 36: Hooks 测试(12 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `apps/web/src/hooks/useApiRequest.test.ts`
|
||||
- 新增: `apps/web/src/hooks/usePaginatedData.test.ts`
|
||||
- 新增: `apps/web/src/hooks/usePermission.test.ts`
|
||||
|
||||
### Task 37: 页面组件测试(19 个)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增 8 个测试文件,对应 8 个核心健康模块页面
|
||||
|
||||
### Task 38: Playwright E2E — 患者管理(1 spec)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `apps/web/e2e/health-patient.spec.ts`
|
||||
|
||||
### Task 39: Playwright E2E — 预约/随访/咨询(3 spec)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `apps/web/e2e/health-appointment.spec.ts`
|
||||
- 新增: `apps/web/e2e/health-follow-up.spec.ts`
|
||||
- 新增: `apps/web/e2e/health-consultation.spec.ts`
|
||||
|
||||
### Task 40: Playwright E2E — 统计仪表板(1 spec)
|
||||
|
||||
**涉及文件**:
|
||||
- 新增: `apps/web/e2e/health-statistics.spec.ts`
|
||||
|
||||
**Phase 4 验收**:
|
||||
- 前端全量覆盖率 ≥ 60%
|
||||
- 健康模块 E2E ≥ 5 个 spec
|
||||
|
||||
---
|
||||
|
||||
## 验证与 CI 门禁
|
||||
|
||||
### Task 41: 后端增量门禁上线(Week 6 后)
|
||||
|
||||
**操作**: 在 CI workflow 中启用后端增量覆盖率检查,新增/修改文件覆盖率 < 80% 时 PR 不允许合并。
|
||||
|
||||
### Task 42: 前端增量门禁上线(Week 9 后)
|
||||
|
||||
**操作**: 同上,启用前端增量覆盖率检查。
|
||||
|
||||
### Task 43: 全量覆盖率验证 + 复盘(Week 12 后)
|
||||
|
||||
**操作**:
|
||||
1. 运行 `cargo llvm-cov --workspace --text` 记录后端全量覆盖率
|
||||
2. 运行 `pnpm test:coverage` 记录前端全量覆盖率
|
||||
3. 对比 spec 目标(后端 80% + 前端 60%),分析差距
|
||||
4. 输出复盘文档到 `docs/discussions/2026-05-XX-test-coverage-retrospective.md`
|
||||
5. 制定后续补测计划(如有必要)
|
||||
|
||||
---
|
||||
|
||||
## 执行原则
|
||||
|
||||
1. **每 Task 完成后立即提交** — 不积压,保持可追溯
|
||||
2. **先验证基础设施** — Phase 0 的 TestApp/TestFixture 必须先通过才能开始 Phase 1
|
||||
3. **测试文件独立于业务代码** — 新增测试文件不修改已有业务逻辑
|
||||
4. **cargo check/test 必须通过** — 每个 Task 完成后运行 `cargo test --workspace` 验证
|
||||
5. **Phase 间复盘** — 每个 Phase 结束后统计覆盖率,与目标对比,必要时调整
|
||||
Reference in New Issue
Block a user