# E2E 测试体系重构方案 **版本**: v1.0 **日期**: 2026-07-25 **状态**: 设计稿 --- ## 一、现状分析 ### 1.1 现有测试概览 | 维度 | 当前状态 | |------|----------| | 测试文件数 | 40 个 spec 文件 | | 覆盖角色 | 6 个 (parent/child/teacher/nutritionist/vendor/admin) | | 框架 | Playwright | | 目标环境 | `http://cfc.iwintrue.com` (通过 `PW_BASE_URL` 配置) | | 测试数据 | 无统一管理,依赖环境存量数据 | ### 1.2 现有问题 | 问题 | 严重程度 | 说明 | |------|:--------:|------| | 重复的认证代码 | 🔴 高 | 6 个 admin 文件各有一套 `ensureLoggedIn`/`login` 函数副本 | | 无认证的 mini-app 测试 | 🔴 高 | parent/child/teacher 角色的 E2E 测试没有登录环节 | | 无测试数据管理 | 🔴 高 | 每次运行依赖环境现有数据,无 reset/seed | | 质量不一致 | 🟡 中 | 10 个文件仅检查页面渲染,无真实断言 | | 角色不清晰 | 🟡 中 | 文件按功能命名而非角色,跨角色文件归属混乱 | | 无 API 断言 | 🟡 中 | 全部是 UI 可见性验证,无后端响应验证 | | 无数据清理 | 🟡 中 | 测试创建的记录会遗留 | ### 1.3 需求范围 - 重构目录为 **角色维度 + 流程维度** 双轴结构 - 支持 8 类角色:parent / child / teacher / nutritionist / butler / admin / vendor - 覆盖全部 1357 个 API 端点中的核心场景 - 基础设施:统一认证 helper、DB reset + seed、测试数据工厂 - 跨角色流程测试(flows) --- ## 二、架构设计 ### 2.1 双轴目录结构 ``` tests/e2e/ │ ├── playwright.config.js # Playwright 配置(已存在,微调) ├── reset-db.sh # 🔧 数据库重置脚本(新增) ├── seed-data.sql # 🔧 种子数据(新增) │ ├── helpers/ # 🔧 基础设施 │ ├── auth.js # 8 类角色登录 helper │ ├── db.js # reset + seed 统一入口 │ ├── fixtures.js # 测试数据工厂 │ └── utils.js # 通用工具 │ ├── roles/ # 角色维度 —— 按操作用户分类 │ ├── parent/ # 家长端 │ ├── child/ # 孩子端 │ ├── teacher/ # 成长规划师 │ ├── nutritionist/ # 健康营养师 │ ├── butler/ # 管家 │ ├── admin/ # 运营管理端 │ │ ├── article/ # 文章管理子模块 │ │ ├── activity/ # 活动管理子模块 │ │ ├── vendor/ # 供应商管理子模块 │ │ ├── audit/ # 统一审核中心 │ │ ├── product/ # 商品管理子模块 │ │ └── system/ # 系统配置子模块 │ └── vendor/ # 供应商/服务商 │ └── flows/ # 流程维度 —— 跨角色业务流 ├── assessment-full-chain/ # 测评全链(家长→系统→测评师→家长) ├── task-lifecycle/ # 任务生命周期(家长创建→孩子完成→家长审核) ├── wish-fulfillment/ # 心愿流转(孩子创建→家长定价→兑换→审批) ├── family-invite-flow/ # 家庭邀请(家长邀请→加入) ├── planner-bind-flow/ # 规划师绑定(规划师邀请→家长接受) └── vendor-onboarding-flow/ # 供应商入驻(申请→审核→上架) ``` ### 2.2 双轴关系 ``` ┌─────────────────────────────────────┐ │ flows/ │ │ 跨角色业务流(串联多个角色操作) │ └─────────────────────────────────────┘ │ ┌───────────────┬───────────┼───────────┬──────────────────┐ ▼ ▼ ▼ ▼ ▼ roles/parent roles/child roles/teacher roles/admin roles/vendor ─────────── ─────────── ───────────── ─────────── ──────────── login login login login login family-mgmt daily-checkin family-binding user-mgmt onboarding task-mgmt mini-games task-assign article/* product-mgmt wish-mgmt task-exec package-mgmt activity/* order-process assessment wish-create assessment/* vendor/* energy energy-view training-plan system/* product family-list audit/* growth-record dashboard membership ─────────── ─────────── ───────────── ─────────── ──────────── nutritionist butler ─────────── ─────────── login login profile-mgmt ai-chat diet-record task-reminder recipe-mgmt health-track meal-recommend ``` **原则**: - `roles/` 下的测试:**单一角色操作**,验证该角色能做什么、不能做什么 - `flows/` 下的测试:**跨角色协作**,串联完整业务流,验证状态流转正确 - `flows/` 测试可以调用 `roles/` 中的辅助函数(如 `loginAs()`)但不能依赖 `roles/` 中的测试用例 --- ## 三、基础设施设计 ### 3.1 统一认证 (helpers/auth.js) ```javascript // 支持 8 种角色,每个角色有独立登录入口和凭证 const ROLES = { parent: { phone: '13701366188', loginType: 'phone' }, child: { phone: '13701366189', loginType: 'phone' }, teacher: { phone: '13800000001', loginType: 'phone' }, nutritionist: { phone: '13800000010', loginType: 'phone' }, butler: { phone: '13800000020', loginType: 'phone' }, admin: { phone: '13800138000', loginType: 'password' }, vendor: { phone: '13800138001', loginType: 'phone' }, assessor: { phone: '13800000030', loginType: 'phone' }, }; // 入口函数 async function loginAs(page, role) { // admin → 走 admin 登录页面 // 其他 → 走 mini-app 登录流程 // 返回 { token, userId, role } } // 在每个测试文件头部调用 test.beforeAll(async ({ browser }) => { const context = await browser.newContext({ storageState: undefined }); const page = await context.newPage(); const auth = await loginAs(page, 'parent'); await context.storageState({ path: STATE_PATH }); // 保存 token 供 API 断言使用 }); ``` ### 3.2 数据库重置 (reset-db.sh + seed-data.sql) ```bash #!/bin/bash # reset-db.sh — 每次 E2E 运行前执行 MYSQL_HOST="192.168.16.251" MYSQL_USER="cfc" MYSQL_PASS="cfc@123" MYSQL_DB="cfc" echo "==> 重置数据库..." mysql -h$MYSQL_HOST -u$MYSQL_USER -p$MYSQL_PASS $MYSQL_DB < seed-data.sql echo "==> 完成" ``` 种子数据需要包含: | 数据 | 内容 | |------|------| | 测试用户 | 每个角色 1-2 个账号,包含家庭关系 | | 测试家庭 | 1 个完整家庭(家长+2个孩子) | | 测试商品 | 3-5 个商品/套餐 | | 测试文章 | 1 篇草稿 + 1 篇已发布 | | 测试活动 | 1 个待审核 + 1 个已发布 | | 测试订单 | 1 个已完成订单 | | 系统配置 | 维度、能量规则、佣金配置 | ### 3.3 测试数据工厂 (helpers/fixtures.js) ```javascript // 生成测试数据的辅助函数 async function createTestUser(db, role, overrides) { /* ... */ } async function createTestTask(db, userId, overrides) { /* ... */ } async function createTestWish(db, childId, overrides) { /* ... */ } // ... ``` ### 3.4 API 断言辅助 (helpers/utils.js) ```javascript // 通用的 API 响应断言 async function assertApiSuccess(response, expectedStatus = 200) { expect(response.status()).toBe(expectedStatus); const body = await response.json(); expect(body.code).toBe(200); return body.data; } async function assertApiError(response, expectedCode, expectedMessage) { const body = await response.json(); expect(body.code).toBe(expectedCode); if (expectedMessage) expect(body.message).toContain(expectedMessage); } ``` ### 3.5 playwright.config.js 调整 ```javascript // 增加全局 setup(DB reset) globalSetup: require.resolve('./helpers/db.js'), // 增加每个 spec 的超时 timeout: 120000, // 增加 retry retries: 1, ``` --- ## 四、角色维度测试设计 ### 4.1 家长 (parent) | 文件 | 场景数 | 现有文件映射 | 优先级 | |------|:------:|-------------|:------:| | `login.spec.js` | 4 | 从 `AuthControllerTest` 反向 | P0 | | `family-management.spec.js` | 9 | `family-member-management.spec.js` | P0 | | `task-management.spec.js` | 5 | 新增(补齐审批/历史) | P1 | | `wish-management.spec.js` | 5 | 从 `wish-exchange-flow.spec.js` 拆分 | P0 | | `assessment-order.spec.js` | 7 | `assessment-order-flow.spec.js` | P0 | | `energy-dashboard.spec.js` | 6 | `energy-system.spec.js` | P0 | | `product-purchase.spec.js` | 9 | `product-purchase.spec.js` | P0 | | `growth-record.spec.js` | 5 | `growth-record-sync.spec.js` | P0 | | `health-report.spec.js` | 4 | 新增 | P1 | | `nutrition-profile.spec.js` | 4 | 从 `nutritionist-flow.spec.js` 拆分 | P1 | | `subscription.spec.js` | 5 | 🔴 **新增(当前零覆盖)** | P1 | | `membership.spec.js` | 3 | `membership-system.spec.js` | P1 | | `ai-chat.spec.js` | 4 | `ai-plan-task-flow.spec.js` | P1 | | `points.spec.js` | 4 | `points-system.spec.js` | P0 | | `consignee.spec.js` | 4 | `consignee-management.spec.js` | P1 | | `contact.spec.js` | 4 | `contact-management.spec.js` | P1 | | `family-earnings.spec.js` | 3 | 🔴 **新增(当前零覆盖)** | P2 | | **小计** | **85** | | | ### 4.2 孩子 (child) | 文件 | 场景数 | 现有文件映射 | 优先级 | |------|:------:|-------------|:------:| | `login.spec.js` | 3 | 🔴 新增(当前无独立孩子登录测试) | P0 | | `daily-checkin.spec.js` | 8 | `daily-checkin-streak.spec.js` | P0 | | `mini-games.spec.js` | 6 | `mini-games-*.spec.js` (3 文件合并) | P0 | | `task-execution.spec.js` | 4 | 新增(完成任务/提交) | P0 | | `wish-create.spec.js` | 3 | 从 `wish-exchange-flow.spec.js` 拆分 | P0 | | `energy-view.spec.js` | 3 | `energy-system.spec.js` | P0 | | `growth-record.spec.js` | 3 | `growth-record-sync.spec.js` | P1 | | **小计** | **30** | | | ### 4.3 成长规划师 (teacher) | 文件 | 场景数 | 现有文件映射 | 优先级 | |------|:------:|-------------|:------:| | `login.spec.js` | 4 | 从 `TeacherLoginTest` 反向 | P0 | | `family-binding.spec.js` | 7 | `planner-bind-invite.spec.js` | P0 | | `package-management.spec.js` | 5 | 🔴 **新增(当前零覆盖)** | P0 | | `task-assignment.spec.js` | 6 | 🔴 新增(任务下发/批量审核) | P0 | | `family-list.spec.js` | 5 | `guide-family-list.spec.js` | P0 | | `training-plan.spec.js` | 4 | 🔴 **新增(当前零覆盖)** | P1 | | `dashboard.spec.js` | 4 | `teacher-dashboard.spec.js` | P1 | | `assessment/` (测评师子角色) | | | | | ├── `recording.spec.js` | 5 | `assessment-order-flow.spec.js` 提取 | P0 | | ├── `appointment.spec.js` | 4 | 🔴 **新增(当前零覆盖)** | P0 | | └── `report-view.spec.js` | 3 | 提取 | P1 | | **小计** | **47** | | | ### 4.4 健康营养师 (nutritionist) — 🆕 | 文件 | 场景数 | 现有文件映射 | 优先级 | |------|:------:|-------------|:------:| | `login.spec.js` | 2 | 🔴 新增 | P0 | | `profile-management.spec.js` | 3 | `nutritionist-flow.spec.js` (拆分) | P0 | | `diet-record.spec.js` | 3 | `nutritionist-flow.spec.js` (拆分) | P0 | | `recipe-management.spec.js` | 4 | `nutritionist-flow.spec.js` (拆分) | P1 | | `meal-recommendation.spec.js` | 3 | 🔴 新增 | P1 | | `family-binding.spec.js` | 2 | `nutritionist-flow.spec.js` (拆分) | P0 | | **小计** | **17** | | | ### 4.5 管家 (butler) — 🆕 | 文件 | 场景数 | 优先级 | |------|:------:|:------:| | `login.spec.js` | 2 | P0 | | `ai-chat.spec.js` | 4 | P0 | | `task-reminder.spec.js` | 3 | P1 | | `health-tracking.spec.js` | 3 | P1 | | **小计** | **12** | | ### 4.6 管理员 (admin) | 文件 | 场景数 | 现有文件映射 | 优先级 | |------|:------:|-------------|:------:| | `login.spec.js` | 2 | 提取统一 | P0 | | `user-management.spec.js` | 5 | 🔴 **新增(当前零覆盖)** | P0 | | `family-management.spec.js` | 4 | 🔴 **新增(当前零覆盖)** | P1 | | `article/workflow.spec.js` | 5 | `article-management.spec.js` | P0 | | `article/category.spec.js` | 3 | 🔴 **新增(当前零覆盖)** | P1 | | `article/tag.spec.js` | 3 | 🔴 新增 | P2 | | `activity/approval.spec.js` | 4 | `activity-registration.spec.js` | P0 | | `activity/config.spec.js` | 3 | 🔴 **新增(当前零覆盖)** | P1 | | `vendor/management.spec.js` | 4 | `vendor-onboarding.spec.js` | P0 | | `audit/article-audit.spec.js` | 3 | `unified-audit-center.spec.js` | P0 | | `audit/butler-audit.spec.js` | 3 | `admin-butler-review.spec.js` | P1 | | `audit/vendor-audit.spec.js` | 3 | 🔴 新增 | P1 | | `product/approval.spec.js` | 4 | `admin-ecom-supplier.spec.js` | P1 | | `product/category.spec.js` | 3 | 🔴 **新增(当前零覆盖)** | P2 | | `system/dimension-config.spec.js` | 4 | 🔴 **新增(当前零覆盖)** | P1 | | `system/energy-config.spec.js` | 4 | `energy-rules-config.spec.js` | P0 | | `system/commission-config.spec.js` | 3 | `admin-commission-config.spec.js` | P1 | | `system/promotion-config.spec.js` | 3 | `admin-promotion-config.spec.js` | P2 | | `system/operation-log.spec.js` | 3 | 🔴 **新增(当前零覆盖)** | P2 | | `membership.spec.js` | 4 | 🔴 **新增(当前零覆盖)** | P1 | | `subscription.spec.js` | 3 | 🔴 **新增(当前零覆盖)** | P1 | | `data-migration.spec.js` | 3 | 🔴 **新增(当前零覆盖)** | P2 | | **小计** | **74** | | | ### 4.7 供应商/服务商 (vendor) | 文件 | 场景数 | 现有文件映射 | 优先级 | |------|:------:|-------------|:------:| | `onboarding.spec.js` | 4 | `vendor-onboarding.spec.js` 提取 | P0 | | `product-management.spec.js` | 5 | `vendor-product-manage.spec.js` | P0 | | `order-processing.spec.js` | 4 | 🔴 **新增(当前零覆盖)** | P1 | | `dan-assessment-vendor.spec.js` | 4 | `dan-assessment-vendor-flow.spec.js` | P1 | | **小计** | **17** | | | --- ## 五、流程维度测试设计 流程测试按 `flows/` 下的独立目录组织,每个目录包含一个完整业务流的多个阶段。 ### 5.1 测评全链 (assessment-full-chain) ``` flows/assessment-full-chain/ ├── flow.spec.js # 主流程测试 ``` 业务流:家长购买测评 → 支付 → 系统分配规划师 → 规划师录入结果 → 家长查看报告 | 阶段 | 角色 | 验证点 | |:----:|:----:|--------| | 1 | 家长 | 选择孩子+规划师 → 创建订单 → 订单状态=待支付 | | 2 | 家长 | 完成支付 → 订单状态=已支付,预约自动创建 | | 3 | 系统 | 预约状态=待确认 | | 4 | 规划师 | 确认预约 → 查看孩子快照 | | 5 | 规划师 | 录入测评结果 → 结果状态=已录入 | | 6 | 家长 | 查看测评报告 → 结果可见 | | 7 | 家长 | 取消未支付订单 → 订单状态=已取消 | API 验证: ``` POST /api/dan-assessment/order/create → code=200, orderId POST /api/dan-assessment/order/pay → code=200, status=paid POST /api/dan-assessment/appointment/confirm → code=200, status=confirmed POST /api/dan-assessment/result/create → code=200, resultId POST /api/dan-assessment/order/detail → code=200, resultId != null ``` ### 5.2 任务生命周期 (task-lifecycle) 业务流:家长创建任务 → 孩子查看/完成 → 家长审核 → 积分发放 | 阶段 | 角色 | 验证点 | |:----:|:----:|--------| | 1 | 家长 | 创建任务(含小游戏任务)→ 任务状态=待完成 | | 2 | 孩子 | 查看今日任务列表 → 新任务可见 | | 3 | 孩子 | 完成小游戏/提交 → 任务状态=待审核 | | 4 | 家长 | 审核通过/驳回 → 审核通过则发放积分 | | 5 | 孩子 | 查看积分 → 积分增加 | ### 5.3 心愿流转 (wish-fulfillment) 业务流:孩子创建心愿 → 家长定价 → 孩子申请兑换 → 家长审批 → 扣减积分 | 阶段 | 角色 | 验证点 | |:----:|:----:|--------| | 1 | 孩子 | 创建心愿 → 心愿状态=待定价 | | 2 | 家长 | 定价 → 心愿有积分值 | | 3 | 孩子 | 申请兑换 → 状态=待审批 | | 4 | 家长 | 审批通过/拒绝 → 通过则扣减积分 | | 5 | 孩子 | 查看积分 → 已扣减 | | 6 | 家长 | 拒绝心愿 → 状态=已拒绝 | ### 5.4 家庭邀请流程 (family-invite-flow) 业务流:家长生成邀请码 → 新用户扫码 → 加入家庭 | 阶段 | 角色 | 验证点 | |:----:|:----:|--------| | 1 | 家长 | 生成家庭邀请码 → 返回 token | | 2 | 新用户 | 输入邀请码 → 绑定到家庭 | | 3 | 家长 | 查看家庭成员列表 → 新成员可见 | | 4 | 家长 | 移除成员 → 成员列表更新 | ### 5.5 规划师绑定流程 (planner-bind-flow) 业务流:规划师生成邀请 → 家长接受绑定 → 规划师客户列表更新 | 阶段 | 角色 | 验证点 | |:----:|:----:|--------| | 1 | 规划师 | 生成绑定邀请 → 返回凭证 | | 2 | 家长 | 验证邀请 → 展示邀请详情 | | 3 | 家长 | 确认绑定 → 绑定成功 | | 4 | 规划师 | 查看客户列表 → 新家庭可见 | | 5 | 规划师 | 解绑 → 关系终止 | ### 5.6 供应商入驻流程 (vendor-onboarding-flow) 业务流:供应商提交入驻 → 管理员审核 → 供应商上架商品 → 用户购买 | 阶段 | 角色 | 验证点 | |:----:|:----:|--------| | 1 | 供应商 | 提交入驻申请 → 状态=pending | | 2 | 管理员 | 审核通过/驳回 → 通过则状态=approved | | 3 | 供应商 | 创建商品 → 商品状态=待审核 | | 4 | 管理员 | 审核商品 → 上架 | | 5 | 用户 | 浏览并购买商品 → 订单创建 | | 6 | 供应商 | 查看订单 → 订单可见 | --- ## 六、质量规范 ### 6.1 每个测试文件必须包含 ```javascript const { test, expect } = require('@playwright/test'); const { loginAs } = require('../../helpers/auth'); const { assertApiSuccess } = require('../../helpers/utils'); test.describe('【角色】模块 - 场景描述', () => { let auth; test.beforeAll(async ({ browser }) => { auth = await loginAs(browser, 'parent'); }); test('[场景N] 用户故事描述 — 期望具体结果', async ({ page }) => { // Given:前置条件 // When:操作 // Then:验证(UI断言 + API断言) }); }); ``` ### 6.2 断言标准 | 等级 | 断言要求 | 示例 | |:----:|----------|------| | **P0** | UI 可见性 + API 响应码 + 关键数据验证 | HTTP 200 + `body.code === 200` + `body.data.orderId` 非空 | | **P1** | UI 可见性 + API 响应码 | HTTP 200 + `body.code === 200` | | **P2** | UI 可见性 | `.toBeVisible()` | 所有 P0/P1 场景必须包含 API 级断言。 P2 场景允许仅 UI 验证。 ### 6.3 API 断言模式 ```javascript // 方式一:通过 page.request 直接验证后端 const response = await page.request.post('/api/family/member/list', { data: { familyId: auth.familyId }, headers: { Authorization: 'Bearer ' + auth.token }, }); const data = await assertApiSuccess(response); expect(data.members.length).toBeGreaterThan(0); // 方式二:混合 UI + API await page.click('.submit-btn'); await expect(page.locator('.success-tip')).toBeVisible(); const orderResp = await assertApiSuccess( await page.request.post('/api/dan-assessment/order/detail', { /* ... */ }) ); expect(orderResp.order.status).toBe('paid'); ``` ### 6.4 数据隔离 - 每个测试文件在 `beforeAll` 中登录 - 每个场景(`test()`)独立验证,不依赖其他场景的副作用 - 数据清理统一在 seed-data.sql 层面解决(每次运行前全量恢复) ### 6.5 错误场景覆盖 每个 P0 场景必须包含 **至少一个错误场景**(异常分支): ``` 场景1: 正常流程 — 期望成功 场景1b: 参数异常(空值/越界/不存在)— 期望合理错误提示 场景1c: 权限异常(无权限角色操作)— 期望 403/500 ``` --- ## 七、实施计划 ### Phase 1:基础设施 + 核心角色重构(2周) | 任务 | 交付物 | 工时 | |------|--------|:----:| | 1.1 编写 `reset-db.sh` + `seed-data.sql` | 数据库重置脚本 | 1天 | | 1.2 编写 `helpers/auth.js` | 8 角色登录 helper | 1.5天 | | 1.3 编写 `helpers/fixtures.js` | 测试数据工厂 | 1天 | | 1.4 编写 `helpers/utils.js` | 通用断言工具 | 0.5天 | | 1.5 调整 `playwright.config.js` | 全局配置 | 0.5天 | | 1.6 重构 `roles/parent/` (6个核心文件) | login, family, wish, assessment, energy, points | 3天 | | 1.7 重构 `roles/child/` (4个核心文件) | login, checkin, games, wish-create | 2天 | | 1.8 重构 `roles/teacher/` (4个核心文件) | login, binding, task, family-list | 2天 | | 1.9 重构 `roles/admin/` (4个核心文件) | login, article, activity, audit | 2天 | ### Phase 2:新增角色 + 流程测试(2周) | 任务 | 交付物 | 工时 | |------|--------|:----:| | 2.1 新增 `roles/nutritionist/` (3个文件) | login, profile, diet-record | 2天 | | 2.2 新增 `roles/butler/` (2个文件) | login, ai-chat | 2天 | | 2.3 新增 `roles/teacher/assessment/` (3个文件) | recording, appointment, report | 2天 | | 2.4 新增 `roles/admin/user-management` | 用户管理 | 1天 | | 2.5 新增 `flows/assessment-full-chain` | 测评全链流程 | 2天 | | 2.6 新增 `flows/task-lifecycle` | 任务生命周期 | 1.5天 | | 2.7 新增 `flows/wish-fulfillment` | 心愿流转 | 1.5天 | | 2.8 新增 `flows/planner-bind-flow` | 规划师绑定流程 | 1天 | ### Phase 3:补齐剩余模块 + 错误场景(2周) | 任务 | 交付物 | 工时 | |------|--------|:----:| | 3.1 补齐 `roles/parent/` 剩余文件 | subscription, membership, ai-chat, growth, health | 3天 | | 3.2 补齐 `roles/admin/` 剩余模块 | system/, product/, vendor/, membership | 3天 | | 3.3 补齐 `roles/vendor/` | onboarding, product, order | 2天 | | 3.4 补齐 `roles/teacher/` 剩余文件 | package, training-plan, dashboard | 2天 | | 3.5 补齐 `roles/nutritionist/` 剩余文件 | recipe, meal-recommend, family-binding | 1天 | | 3.6 补齐 `flows/` 剩余流程 | family-invite, vendor-onboarding | 2天 | | 3.7 为所有 P0 场景补充错误场景 | 异常分支 | 2天 | | 3.8 删除旧文件 | 清理旧目录 | 0.5天 | --- ## 八、运行方式 ```bash # 1. 重置数据库 bash tests/e2e/reset-db.sh # 2. 运行全部测试 npx playwright test tests/e2e/ # 3. 按角色运行 npx playwright test tests/e2e/roles/parent/ npx playwright test tests/e2e/roles/admin/ # 4. 按流程运行 npx playwright test tests/e2e/flows/assessment-full-chain/ # 5. 单文件 npx playwright test tests/e2e/roles/parent/family-management.spec.js # 6. 自定义环境 PW_BASE_URL=http://staging.cfc.iwintrue.com npx playwright test ``` --- ## 九、文件变更清单 ### 新增 | 文件 | 数量 | |------|:----:| | `tests/e2e/helpers/auth.js` | 1 | | `tests/e2e/helpers/db.js` | 1 | | `tests/e2e/helpers/fixtures.js` | 1 | | `tests/e2e/helpers/utils.js` | 1 | | `tests/e2e/reset-db.sh` | 1 | | `tests/e2e/seed-data.sql` | 1 | | `tests/e2e/roles/` 目录下 spec 文件 | ~58 | | `tests/e2e/flows/` 目录下 spec 文件 | ~6 | | **新增合计** | **~70 文件** | ### 删除 | 文件 | 数量 | |------|:----:| | 旧的 `tests/e2e/*.spec.js` 文件 | 40 | ### 修改 | 文件 | 数量 | |------|:----:| | `tests/e2e/playwright.config.js` | 1 | --- ## 十、验收标准 | 标准 | 说明 | |------|------| | 所有测试可独立运行 | `npx playwright test tests/e2e/roles/parent/` 通过 | | 每次运行前 DB 自动重置 | 全局 setup 脚本执行 reset-db.sh | | 无重复认证代码 | 所有认证走 `helpers/auth.js` | | 无纯占位测试 | 每个 `test()` 有至少一个 `expect()` | | 所有 P0 场景含错误路径 | 至少 1 个正常 + 1 个异常 | | 流程测试验证跨角色状态流转 | API 断言验证状态变更 | | 旧文件全部移除 | 无 `tests/e2e/*.spec.js` 残留 |