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)
// 支持 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)
#!/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)
// 生成测试数据的辅助函数
async function createTestUser(db, role, overrides) { /* ... */ }
async function createTestTask(db, userId, overrides) { /* ... */ }
async function createTestWish(db, childId, overrides) { /* ... */ }
// ...
3.4 API 断言辅助 (helpers/utils.js)
// 通用的 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 调整
// 增加全局 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 每个测试文件必须包含
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 断言模式
// 方式一:通过 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天 |
八、运行方式
# 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 残留 |