diff --git a/docs/superpowers/specs/2026-04-28-e2e-testing-design.md b/docs/superpowers/specs/2026-04-28-e2e-testing-design.md new file mode 100644 index 0000000..a1d9ef7 --- /dev/null +++ b/docs/superpowers/specs/2026-04-28-e2e-testing-design.md @@ -0,0 +1,603 @@ +# E2E 测试设计规格 — HMS 健康管理平台 + +> 日期: 2026-04-28 | 状态: 设计中 + +## Context + +HMS 健康管理平台当前 E2E 测试仅有 10 个基础用例(登录/用户/插件/租户隔离),健康模块 ~27 个 Web 页面路由和微信小程序端完全无 E2E 覆盖。wiki 已将此标注为 P2 缺口。本设计旨在建立双端(Web + 小程序)的流程链路式 E2E 测试体系。 + +## 大纲 + +1. 整体架构与目录结构 +2. 关键业务链路定义 +3. 测试数据策略与 API Client +4. Page Object 与 MCP Helper 设计 +5. 执行策略与 CI-Ready 设计 + +--- + +## §1 整体架构与目录结构 + +### 设计决策 + +| 维度 | 选择 | 原因 | +|------|------|------| +| 覆盖范围 | Web 全量 + 小程序并行 | 双端同步覆盖,最大化业务保障 | +| 测试深度 | 关键流程冒烟测试 | 务实覆盖最重要的用户路径 | +| 小程序实现 | WeChat MCP 自动化 | 利用已有 MCP 联调能力 | +| 测试架构 | 双端独立框架 | Web 用 Playwright,小程序用 Vitest + MCP | +| 测试数据 | API 驱动自建自毁 | 每个测试独立创建/清理数据 | +| CI 策略 | 本地优先,CI-ready 设计 | 环境变量驱动,未来可接入 GitHub Actions | + +### 目录结构 + +``` +apps/web/e2e/ # Web 端 E2E(Playwright) +├── flows/ # 业务链路测试 +│ ├── patient-journey.spec.ts # 患者全流程 +│ ├── vital-signs-flow.spec.ts # 体征数据链路 +│ ├── appointment-flow.spec.ts # 预约排班链路 +│ ├── follow-up-flow.spec.ts # 随访管理链路 +│ └── alert-flow.spec.ts # 告警处理链路 +├── smoke/ # 基础冒烟(迁移现有 4 个 spec) +│ ├── login.spec.ts +│ ├── users.spec.ts +│ ├── plugins.spec.ts +│ └── tenant-isolation.spec.ts +├── fixtures/ # 测试基础设施 +│ ├── auth.fixture.ts # 认证 fixture(增强现有) +│ ├── api-client.ts # API 数据准备/清理客户端 +│ └── test-data.ts # 测试数据工厂函数 +├── pages/ # 轻量 Page Object(仅关键页面) +│ ├── login.page.ts +│ ├── patient-list.page.ts +│ ├── patient-detail.page.ts +│ ├── appointment.page.ts +│ └── health-data.page.ts +└── playwright.config.ts # 增强配置 + +apps/miniprogram/e2e/ # 小程序端 E2E(MCP 自动化) +├── flows/ # 业务链路测试 +│ ├── patient-health-view.spec.ts # 患者查看健康数据 +│ ├── vital-signs-input.spec.ts # 体征录入 +│ ├── points-flow.spec.ts # 积分签到兑换 +│ └── mall-flow.spec.ts # 积分商城 +├── helpers/ # MCP 封装 +│ ├── mcp-client.ts # MCP 工具调用封装 +│ ├── auth.helper.ts # 小程序登录/Token 注入 +│ └── navigation.helper.ts # 页面导航封装 +├── check-readiness.ts # 环境就绪检查 +└── vitest.config.ts # 测试运行器配置 +``` + +### 关键原则 + +1. 现有 4 个 smoke test 原地迁移到 `smoke/` 目录,逻辑不变 +2. Web 端保持 Playwright,小程序端用 Vitest + `miniprogram-automator`,各自独立运行 +3. 两端 API client 逻辑保持一致但代码各自维护(Web 运行在 Node,小程序也运行在 Node,可考虑后续抽取共享包) +4. Page Object 只封装关键页面,随访/告警等简单页面直接在 spec 中操作 +5. 每条链路自包含(API 准备所需数据),不依赖其他链路的执行顺序 +6. 所有 Page Object 使用 Hash Router 路径格式(`/#/health/patients`) + +## §2 关键业务链路定义 + +### Web 端链路(5 条) + +**Flow 1: 患者全流程 `patient-journey.spec.ts`** +``` +登录 → 患者列表页 → 创建患者 → 查看患者详情 → 编辑患者信息 +→ 分配医生 → 添加家族成员 → 删除测试数据 +``` +验证点:患者 CRUD、详情页数据完整性、医生关联、家族成员管理 + +**Flow 2: 体征数据链路 `vital-signs-flow.spec.ts`** +``` +登录 → 选择患者 → 录入体征数据(血压/心率/血糖) +→ 查看体征列表 → 查看趋势图 → 录入化验报告 → 审核报告 +→ 清理数据 +``` +验证点:体征录入表单、列表展示、趋势图表渲染、化验报告上传与审核 + +**Flow 3: 预约排班链路 `appointment-flow.spec.ts`** +``` +登录 → 创建医生 → 设置排班 → 患者列表 → 创建预约 +→ 查看预约列表 → 更新预约状态 → 清理数据 +``` +验证点:排班日历交互、预约创建、状态流转(待确认→已确认→已完成) + +**Flow 4: 随访管理链路 `follow-up-flow.spec.ts`** +``` +登录 → 创建随访模板 → 批量创建随访任务 → 查看任务列表 +→ 完成随访(填写记录)→ 查看随访记录 → 清理数据 +``` +验证点:模板管理、批量操作、任务分配、随访记录填写 + +**Flow 5: 告警处理链路 `alert-flow.spec.ts`** +``` +登录(API) → 创建告警规则(低阈值,如心率 > 50) +→ 录入触发体征数据(API 创建心率为 110 的体征)→ 轮询等待告警生成(最多 10s) +→ 查看告警列表(UI)→ 确认告警 → 处理告警 → 查看告警规则 +→ 停用规则 → 清理数据(规则 + 体征 + 告警) +``` +验证点:告警规则配置、告警自动生成、列表/仪表盘展示、状态流转(待处理→已确认→已处理) +**异步处理说明:** 告警由后台任务根据规则匹配体征数据自动生成。测试通过 API 创建低阈值规则 + 触发数据,然后轮询告警列表 API 等待告警出现(`await expect.poll(() => api.getAlerts(), { timeout: 10_000 })`)。 + +### 小程序端链路(4 条) + +**Flow 6: 患者健康数据查看 `patient-health-view.spec.ts`** +``` +MCP 登录 → 首页 → 查看今日体征摘要 → 查看体征趋势 +→ 查看随访任务列表 → 查看化验报告 +``` + +**Flow 7: 体征数据录入 `vital-signs-input.spec.ts`** +``` +MCP 登录 → 进入录入页 → 填写血压/心率 → 提交 +→ 验证数据出现在列表 → 清理数据 +``` + +**Flow 8: 积分签到兑换 `points-flow.spec.ts`** +``` +MCP 登录 → 每日签到 → 查看积分余额 → 浏览商品 +→ 兑换商品 → 查看订单列表 +``` + +**Flow 9: 积分商城 `mall-flow.spec.ts`** +``` +MCP 登录 → 商城首页 → 浏览商品分类 → 查看商品详情 +→ 查看线下活动 → 活动报名 +``` + +### 链路覆盖矩阵 + +| 业务模块 | Web 链路 | 小程序链路 | API 链路(已有) | +|---------|---------|-----------|---------------| +| 患者管理 | Flow 1 | — | Chain 1 | +| 体征/健康数据 | Flow 2 | Flow 6, 7 | Chain 1, 2 | +| 预约排班 | Flow 3 | — | Chain 1 | +| 随访管理 | Flow 4 | Flow 6 | Chain 1 | +| 告警系统 | Flow 5 | — | — | +| 积分体系 | — | Flow 8 | Chain 4 | +| 积分商城 | — | Flow 9 | Chain 4 | + +未覆盖模块说明: +- **咨询管理**(2 页面)— 有完整 API 链路,但实时消息交互难以用 E2E 验证,建议 API 集成测试覆盖 +- **内容/文章管理**(4 页面)— CRUD 操作较标准,优先级低于核心医疗流程 +- **AI 分析**(3 页面)— 依赖外部 AI 服务,不稳定,建议 mock 测试 +- **统计仪表盘**(5 页面)— 数据聚合展示,E2E 价值有限,建议视觉回归测试 + +## §3 测试数据策略与 API Client + +### 核心原则 + +API 驱动自建自毁:每个测试通过 API 创建所需数据,测试结束后清理。不依赖数据库预置状态。 + +### API Client + +后端所有实体使用乐观锁(`version` 字段),更新/删除操作必须携带 version。API Client 的所有方法返回完整实体(含 version),清理操作使用返回的 version。 + +```typescript +// fixtures/api-client.ts + +interface VersionedEntity { id: string; version: number } + +class ApiClient { + private token: string; + private baseUrl: string; + + // 认证 + async login(username: string, password: string): Promise + async loginAsAdmin(): Promise + + // 患者数据工厂 — 返回含 version 的完整实体 + async createPatient(overrides?: Partial): Promise + async updatePatient(id: string, version: number, data: Partial): Promise + async deletePatient(id: string, version: number): Promise + + // 医生数据工厂 + async createDoctor(overrides?: Partial): Promise + async deleteDoctor(id: string, version: number): Promise + + // 体征数据工厂 + async createVitalSigns(patientId: string, overrides?: Partial): Promise + async deleteVitalSigns(patientId: string, id: string, version: number): Promise + + // 预约数据工厂 + async createAppointment(overrides?: Partial): Promise + async updateAppointmentStatus(id: string, version: number, status: string): Promise + async deleteAppointment(id: string, version: number): Promise + + // 随访数据工厂 + async createFollowUpTemplate(overrides?: Partial): Promise