e2e-testing
对真实运行系统做端到端验证:按业务旅程编排步骤、跨步骤共享状态,验证跨组件最终一致状态。触发:"跑一遍完整流程看看对不对"、"真实链路测试"、"端到端验证"、"全链路验证"、"检查跨系统终态"。
SKILL.mdskills/e2e-testing/SKILL.md
GitHub端到端真实操作测试(e2e-testing)
概述
目的:把"端到端验证"从手点多系统、肉眼比对,变成"AI 读旅程、编排步骤、跑真实操作、验跨组件终态"。针对真实运行中的系统执行完整业务旅程(注册→下单→支付→查状态…),验证代码实现是否符合需求/设计规格(黑盒验收),而非"代码能跑通就行"。
两个验证维度:
- 断言式 e2e(基础):预设 Scenario/Step/assert,跑真实链路验正确性(PASS/FAIL)。见「工作流程」。
- 动态体验验证(增强):e2e 通过后,agent 像真人一样操作系统,观察并评估体验质量、发现断言覆盖不到的问题。见「动态体验验证」。
验收定位(黑盒 · 需求驱动):
- e2e 是黑盒验收:断言锚定需求/设计文档,而非代码内部实现。只关心「给定入参 → 返回/副作用是否符合规格」,不读内部函数、不依赖内部状态、不为迎合实现而写断言。
- 与单元测试划界:单测验证内部逻辑(白盒、可 mock、快);e2e 验证对外契约与跨组件终态(真实链路、不 mock、慢)。两者物理分离(见「目录与隔离」)。
与 api-testing 的关系:api-testing 聚焦单个 HTTP 接口的"连通性 + 业务断言",彼此隔离、数据是构造的。本技能不重复实现接口测试,而是在 api 类步骤上仅引用 api-testing 已文档化的约定(响应结构、业务断言、凭证脱敏、报告风格),把其能力作为 e2e 编排中的一个动作类型。具体约定见下文「与 api-testing 的约定引用」与 reference.md。
使用场景:
- 用户说"帮我跑一遍完整下单流程""做个端到端验证""真实链路测试一下"
- 需要验证跨系统终态:下单后 DB 是否落库、消息是否发出、库存是否扣减
- 一个操作的输出要喂给后续操作(如建出的 user_id 用于下单)
- 涉及真实副作用且需要 setup/teardown 与确认门禁
- 动态体验:e2e 通过后,用户说"帮我体验一下这个功能好不好用""验收一下真实体验""看看反馈够不够全面"→ 走「动态体验验证」流程
何时不使用本技能(反例,避免误用):
- 只想测单个 HTTP 接口(连通性 + 单接口业务断言)→ 用
api-testing - 系统尚未运行 / 无需真实环境(纯逻辑、可 mock)→ 用单元测试(快、隔离)
- 只要浏览器冒烟(页面能打开、无崩溃)→ 轻量 UI 检查即可,无需完整旅程编排
- 对存量前端做体验体检(点一遍挑体验问题 / 看加载性能,非验收场景)→ 用
frontend-walkthrough - 只做静态验证(格式 / 配置 / 规则检查)→ 用对应专项工具,e2e 编排是过度设计
目录与隔离(tests/e2e)
e2e 测试产物必须与单元测试物理分离,避免被单测 CI 误跑、误用配置或混入白盒用例。
- 约定目录:所有 e2e 场景定义、生成的客户端/脚本、运行产物与报告统一放在
tests/e2e/(不要放在tests/、test/、__tests__/等单测目录,也不要与单测文件同目录)。 - 单测排除 e2e:单元测试套件不得执行
tests/e2e/。按所用框架配置排除:- pytest:在
pyproject.toml/pytest.ini加norecursedirs = tests/e2e,pytest 收集时跳过该目录(单测目录本身用testpaths指向,如testpaths = ["tests/unit"]);CI 中 e2e 单独以pytest tests/e2e运行。 - unittest(Python):discover 时指定单测目录/ pattern,e2e 单独
discover tests/e2e。 - Node(jest/vitest):
testPathIgnorePatterns加入tests/e2e,e2e 用独立testMatch或脚本运行。 - 通用:CI 拆两个 job——
unit(快、隔离)与e2e(需真实环境 +.env.e2e),互不影响。
- pytest:在
- env 文件不入库(
.env.e2e优先、回退.env):见「敏感信息外部化」。
需求绑定(requirement_ref)
e2e 是验收型测试,判据必须来自需求/设计,而非代码。每个 Scenario 必须绑定需求来源:
- 输入即需求文档:执行 e2e 前,先确定被判定的需求/设计文档(或对话中明确的需求条目)。若用户未提供需求来源,须确认,不臆测终态。
requirement_ref字段:Scenario 顶层声明requirement_ref(如REQ-register-order),指向需求条目 ID;场景内的断言应可追溯到该规格。- 断言对照规格:写
assert时以需求描述的"给定 X 应得到 Y"为判据,只校验入参→返回/副作用,不引入对代码内部实现的假设。 - 写断言前不读实现代码:AI 应仅依据需求文档 + 对外接口契约(入参/返回)编写
assert,避免先读源码再写"能通过"的断言,防止迎合实现而非验收需求。
核心概念
💡 本技能是给 AI 的编排规范,而非被独立引擎解析执行的 DSL:下方
Step/Context/${ctx.x}是 AI 的认知与编排框架。AI 在运行时按约定自行选择工具并实现每一步(如api步骤选 httpflex 或项目自有客户端、db步骤选对应驱动),而非由某解析器机械读取 YAML。文档中的 YAML 示例仅用于表达"意图与结构"。
1. Scenario(业务旅程)
一次完整验证的目标,例如"用户注册并下单"。必须绑定需求/设计文档(见「需求绑定」):包含 requirement_ref(对应需求条目 ID)、env(环境信息,值来自 env 文件:.env.e2e 优先,回退 .env)、credentials(脱敏后的凭证,值来自 env 文件)、有序的 steps 列表。
2. Step(抽象可扩展步骤)
统一的步骤契约,使不同类型的动作能被同一引擎编排。完整字段见 reference.md:
- id: create_order
type: api # 步骤类型(见下方目录)
name: 创建订单
depends_on: [register] # 顺序/并行依赖(决定执行次序)
config: { ... } # 类型相关配置
produces: [order_id] # 执行后写回 Context 的键
on_fail: abort # abort(默认) / continue / retry
assert: { ... } # 可选内联断言
3. Context(跨步骤状态流转)—— 本技能灵魂
一张跨步骤共享的状态字典,让真实操作的输出在旅程中流动:
ctx = {
env: { base_url, env_name, ... },
credentials:{ token, cookie, ... }, # 运行时会话内可持完整凭证以发起真实请求
data: { user_id, order_id, ... } # 业务实体,由 step.produces 写入
}
⚠️ 凭证脱敏边界:
ctx.credentials在 AI 运行会话内存中可持有完整 token/cookie(否则无法发起真实请求);仅在写入文件或展示给用户时做脱敏(只显前缀,如Bearer eyJ…)。切勿将完整凭证写入ctx.data或任何落盘文件。
取值采用 A+B 结合:
- A. 依赖顺序:
depends_on: [register]决定执行先后,并支持无依赖步骤并行。 - B. 占位符取值:step 配置中用
${ctx.data.user_id}(或简写${user_id}优先解析ctx.data)引用上游产出,执行前统一解析。 - 详见
reference.md §Context。
4. Setup / Teardown(生命周期)
setup:旅程前准备(建测试租户、清旧数据、起依赖服务)。teardown:旅程后清理(删测试数据、释放资源)。真实操作有副作用时强烈建议对称清理;缺失时必须在报告中提示。- 必须幂等:二者都应支持旅程重复执行——
setup先处理"数据已存在"、teardown容错"数据已不存在",避免二次运行报错或污染。详见reference.md §3.9/3.10。
5. Safety Gate(安全门禁,中等强度)
- 写/删等危险操作需用户显式确认后才执行。
- 不强制 dry-run,但提供 dry-run 预览(只打印将执行的操作,不落地)。
- 环境可指定;若指向生产 → 强告警但不硬阻断。
- 凭证脱敏:token/cookie 只在 Context 与报告中存前缀(如
Bearer eyJ…),不回显完整凭证。- 详见
reference.md §安全门禁。
- 详见
敏感信息外部化(.env.e2e 主,兼容 .env)
🔐 与「凭证脱敏」互补:凭证脱敏管出口(报告/落盘不回显完整凭证);本节点管入口(测试定义文件里禁止出现真实 secret/endpoint)。
e2e 需要真实凭证才能发起请求,但测试定义文件(scenario/脚本)中禁止内联任何真实密钥、token、URL、DB 连接串等敏感信息:
- 一律外部化到 env 文件:定义文件中只写变量引用,如
${ENV.API_BASE_URL}、${ENV.API_TOKEN};真实值由运行时的 env 文件注入。- 首选
.env.e2e:避免与应用自身.env混淆,且应用默认的.env加载器不会自动加载它,天然隔离。若.env.e2e不存在,回退读取项目根.env(兼容已有项目),此时.env视为 e2e 专用来源、不再被应用默认.env加载器当作应用配置。 - 加载与解析:
load_dotenv('.env.e2e')(若存在)否则load_dotenv('.env')(python-dotenv)或等价方式;解析时机在旅程启动、阶段 2 之前:定义文件中的${ENV.XXX}占位符先由 env 文件取值——ENV.API_BASE_URL→ctx.env.base_url、ENV.API_TOKEN→ctx.credentials.token(去掉ENV.前缀映射到ctx.env/ctx.credentials),再由「Context 解析」统一处理${ctx.x}。定义文件本身始终保持无密。 - 启动前自检:执行 e2e 前,AI 应确认实际使用的 env 文件未被 git 跟踪——
git check-ignore .env.e2e(或回退时的.env)有命中即安全;若被跟踪(无忽略),先提醒用户将其加入.gitignore,避免密钥误入库。
- 首选
- 提供模板
.env.e2e.example:列出所有需要的键(如API_BASE_URL=、API_TOKEN=),留空或填占位,提交入库供他人复制为.env.e2e(回退.env时同样可复制为.env)。 - env 文件必须 gitignore:绝不提交真实的
.env.e2e/.env;在.gitignore中加入.env.e2e(及广义敏感项),仅.env.e2e.example入库。 - 禁止项:definition/脚本里不得出现
base_url: "https://prod..."、token: "Bearer eyJ真实串"、password: "..."等字面值;host、key/secret 均从 env 文件取。
工作流程(7 阶段)
[0]解析意图 → [1]拆 step+依赖 → [2]setup+建 Context → [3]按序/并行执行
→ [4]跨步断言+终态校验 → [5]teardown → [6]出 journey 报告
阶段 0:解析测试意图
- 定位需求来源:按「需求绑定」章节确认被判定的规格并记录
requirement_ref;用户未提供需求来源时须确认,不臆测终态。 - 提取目标业务旅程、涉及的环境与凭证(按「敏感信息外部化」约定从 env 文件注入,缺失须确认)、期望终态(如"订单落库且库存-1",须可追溯至需求条目)。
阶段 1:拆解为 Scenario + Steps
将旅程拆成步骤,标注每个 step 的 type 与 depends_on,并标出哪些 step 产出哪些 key(produces)供下游 ${ctx.x} 引用。具体用哪些类型由被测功能决定(不预设固定集)。
- 有索引时先用(挑关键路径 + 定终态校验点):仓库已建
.fe-index/→use_skill("index-lookup")读INDEX.md匹配涉及文件——前端apis/*.md/pages/*.md给出"这个操作走哪些接口",后端tables.md/modules/*.md给出"终态该落在哪张表、哪些模块会连带变",据此选跨组件断言点;无索引 / 未命中 / 过期 → 按原流程,不阻塞
阶段 2:搭建 Context(执行 setup)
先跑 setup 类步骤,初始化 ctx.env / ctx.credentials / ctx.data。
阶段 3:按序 / 并行执行 Steps
- 按
depends_on拓扑排序;无依赖链的步骤可并行。 - 执行前解析
${ctx.x}占位符。 api类步骤遵循 api-testing 约定发请求并做业务断言。- 异步/最终一致处用
wait步骤轮询,直到条件满足或超时。 - 失败处理:默认
abort整个旅程(后续步骤依赖前置状态);独立探针标continue;抖动标retry。 - 根因不明时转排错:失败若非编排配置问题(
produces/depends_on写错、断言口径错),而是疑似服务逻辑、环境、数据状态或异步时序导致,调用use_skill("debug")定位根因——本 skill 判定「是否失败」,不负责定位「服务为什么失败」。
阶段 4:跨步断言 + 终态校验
- 每个 step 的内联
assert在自身执行后校验。 - 独立的
assert步骤可做跨 step 的终态比对(如"DB 状态 == API 返回状态")。 db/mq类步骤直接验证真实落地(落库行、发布事件)。
阶段 5:Teardown 清理
执行 teardown 类步骤,回滚/清理真实副作用;缺失则报告中显式提示。
阶段 6:出 Journey 级报告
按下方模板输出(风格对齐 api-testing)。
Step 类型目录(概览,契约见 reference.md)
| 类型 | 用途 | 典型 produces |
|---|---|---|
api |
HTTP 调用(遵循 api-testing 约定) | 响应 data 中的业务键 |
db |
数据库查询/执行,校验真实落库 | 查询结果/受影响行 |
ui |
浏览器交互(真实页面) | 提取的 DOM 值/状态 |
mq |
消息发布/消费,校验事件真实发出 | 收到的消息 |
cli |
命令行/脚本执行 | stdout/exit code |
wait |
轮询条件直到满足/超时(异步最终一致) | 轮询结果 |
assert |
纯跨步校验,无副作用 | 无 |
transform |
纯计算/派生值写入 ctx,无副作用 | 派生键 |
setup |
旅程前准备 | 测试数据/环境句柄 |
teardown |
旅程后清理 | 无 |
目录为示例且可扩展:被测功能需要其他真实操作类型时,按统一 Step 契约新增即可。
与 api-testing 的约定引用
当 step.type == api 时,引用(不运行时调用)api-testing 技能(skills/api-testing)已文档化的规范:
- 响应结构:归一化为
{ result: bool, code: int, message: str, data: any };失败也返回结构不抛异常。 - 业务断言:不仅看
code,还要校验data的字段存在性 / 类型 / 取值(可取嵌套data.user.name)。仅借鉴该断言思路(校验 data 而非只看 code),具体 HTTP 客户端由被测项目的工具决定,不强依赖 httpflex——可用的库都可(项目自有客户端、requests、httpx 等),只要产出归一化的{result,code,message,data}结构供本技能做assert即可。 - 凭证脱敏:token/cookie 只显前缀,不回显完整凭证。
- 报告风格:明细表 + 失败根因,与本技能 journey 报告对齐。
若项目已用 httpflex-py,可直接照搬
api-testing/reference.md的客户端模板生成api步骤客户端;否则按项目既有方式发请求,只需遵循上述响应结构与业务断言约定。本技能只负责编排与状态流转,不绑定具体 HTTP 实现。
报告模板(Journey 级)
# E2E 测试报告:{scenario 名}
## 概览
- 通过步骤:X / 总 Y(teardown 不计入判定)
- 环境:staging.api.x.com(env_name: staging)
- 旅程状态:✅ PASS / ❌ FAIL(abort 于 step: create_order)
## 明细
| 步骤 | 类型 | 状态 | 关键 evidence | 失败根因 |
|------|------|------|---------------|----------|
| register | api | ✅ | code=201, data.id=123 | — |
| create_order | api | ✅ | code=201, order_id=789 | — |
| db_check | db | ✅ | row exists, status=created | — |
| mq_check | mq | ❌ | 未收到 order.created | 事件未发布/主题不匹配 |
...
## 副作用清单(供审计/teardown)
- 已创建:user_id=123, order_id=789
- 已清理:teardown 删除上述数据 ✅ / ⚠️ 未清理,请手动处理
## 建议
- mq_check 失败:检查订单服务是否确实发布 order.created 事件。
动态体验验证(增强维度)
定位
断言式 e2e 验证"功能对不对"(预设断言 PASS/FAIL);动态体验验证在 e2e 通过后,验证"用起来好不好"——agent 像真人 QA / 体验官,在真实环境亲手操作、观察、判断,发现断言覆盖不到的体验问题(反馈不全、错误提示不友好、可优化点)。
与断言式 e2e 的关系:动态体验是断言式 e2e 的进阶层,不是替代。两者共享真实环境、setup/teardown、安全门禁、敏感信息外部化等基础设施,但驱动方式不同:
| 维度 | 断言式 e2e | 动态体验验证 |
|---|---|---|
| 驱动 | 断言驱动(预设 expected,比对 actual) | 观察驱动(无预设断言,边做边看) |
| 产物 | tests/e2e/ 可复跑脚本 |
不落盘代码,产出体验观察记录 + 报告 |
| 判定 | PASS / FAIL | 符合预期?+ 体验质量 + 优化建议 |
| 路径 | 预设旅程 + 设计边界 | 白盒规划覆盖 + 主动探索负面路径 |
| 关注 | 结果正确性 | 正确性 + 反馈全面性 + 错误反馈友好度 + 可优化点 |
核心原则:白盒规划 + 黑盒体验(铁律)
- 白盒规划:体验计划阶段读代码实现,识别每个分支/功能点,规划要体验的路径,确保覆盖完整(不遗漏代码里的分支)。
- 黑盒体验:体验执行阶段像真人操作 + 观察,不读代码内部,对错由需求规格 + 合理用户预期决定。
- 边界铁律:读代码只为规划覆盖路径,不为写判据。体验执行时若读代码迎合实现,会破坏验收根基。
与断言式 e2e「写断言前不读实现代码」原则的关系:断言式 e2e 完全不读代码(防迎合实现写断言);动态体验只在规划阶段读代码(识别分支确保覆盖),执行阶段同样不读代码。两者在"判据不来自代码"上一致。
前置门禁:e2e 先通过
动态体验必须在断言式 e2e 通过后进行:
- 先跑与本次体验范围对应的 e2e 场景(不必全量无关场景),必须全部 PASS。
- 不通过 → 停止体验,先修 e2e 暴露的正确性问题。基本正确性没保证时,谈体验质量无意义。
- 通过 → 进入分批体验循环。
- 无对应 e2e 场景时(新功能/未覆盖模块):至少跑通基本冒烟(核心路径可达)后再体验,并在体验报告中标注"未经 e2e 验证",提示结论置信度。
工作流程(分批循环)
[前置门禁] 对应范围 e2e 全 PASS
↓ 不通过 → 停止,先修正确性问题
[分批循环] 每个批次:
① 体验计划(白盒):读代码 → 识别分支/功能点 → 出本批体验计划
② 体验执行(黑盒):按计划操作+观察 → 正面/边界/负面路径
③ 体验评估:正确性 + 反馈全面性 + 错误反馈友好度 + 可优化点
④ 用户确认 → 下一批
[产出] 体验报告
阶段 D0:前置门禁
- 确定本次体验的功能范围,跑对应 e2e 场景,必须全 PASS。
- 确认环境与凭证(沿用「敏感信息外部化」约定)。
阶段 D1:体验计划(白盒,分批)
- 读代码:按批次范围阅读功能实现代码,识别分支/功能点(if/else、错误处理路径、不同输入路径、边界条件等)。
- 映射为体验点:每个代码分支 → 对应的用户可感知行为 → 设计一个体验动作。
- 规划路径:每个体验点覆盖正面(正常操作)、边界(极端输入)、负面(故意错误操作)三类。
- 分批:代码庞大时按模块/功能域分批,体验计划分批创建——每批先出该批计划,执行确认后再规划下一批,不一次性规划全部。每批 ≤8 个体验点为宜(超出则拆分)。
- 计划内容:分支清单 → 体验动作 → 预期体验(正确性 + 体验关注点)→ 负面路径设计。模板见
reference.md。
阶段 D2:体验执行(黑盒)
- 像真人操作:按计划亲手配置、启动、操作(发请求、点 UI、看日志),不读代码内部。
- 执行隔离约束:以用户视角操作,不引用 D1 读到的内部实现细节;观察到的异常即便代码里有对应处理(如 try-except 吞异常),仍按用户感知评估(用户看不到内部处理,只看到结果)。
- 即时观察:边操作边记录输出——返回结构、提示信息、响应速度、错误反馈。
- 负面路径:故意执行错误操作(输错密码、非法参数、越权请求),观察系统反馈是否合理、友好。
- 不落盘代码:agent 运行时即时操作,不生成可复跑测试脚本(区别于断言式 e2e)。
阶段 D3:体验评估
对每个体验点,从四个维度评估:
- 正确性:结果是否符合需求规格(仍锚定需求,不锚定代码)。
- 反馈全面性:返回/提示信息是否充分(字段、上下文、下一步引导)。
- 错误反馈友好度:负面路径下,错误提示是否清晰、可操作(而非含糊/技术化/无引导)。
- 可优化点:即使正确,是否有体验改善空间(冗余步骤、信息缺失、交互不顺)。
阶段 D4:确认与下一批
- 每批体验完,输出该批体验小结,用户确认后再规划下一批。
- 全部批次完成 → 汇总为体验报告。
安全门禁(沿用 e2e + 负面路径约束)
动态体验沿用断言式 e2e 的安全门禁,并补充负面路径约束:
- 危险写操作仍需显式确认(db 写、cli 删除、非幂等 api 写/删)。
- 负面路径限定为只读/可回滚:故意错误操作仅限"输错密码、非法参数、越权请求"等不产生真实破坏的动作;不做真实破坏性写操作(如真实删除数据)。
- 负面路径副作用判定(执行前评估):纯查询 / 鉴权失败拒绝类 → 可直接执行;可能成功越权读取他人数据或触发写副作用的 → 需用户确认或跳过(越权读取成功本身是安全事件,非"只读无害")。
- 生产环境强告警,优先非生产。
- 凭证脱敏同 e2e。
体验报告
# 动态体验报告:{功能/模块名}
## 前置门禁
- 对应 e2e 场景:X 个,全部 PASS ✅
## 体验范围(分批)
- 批次1:{模块A}(N 个体验点)
- 批次2:{模块B}(M 个体验点)
## 体验明细
| 体验点 | 路径类型 | 正确性 | 反馈全面性 | 错误反馈友好度 | 可优化点 |
|--------|----------|--------|-----------|---------------|----------|
| 登录-正常 | 正面 | ✅ | 返回含 token+用户信息 | — | — |
| 登录-错密码 | 负面 | ✅ | — | "密码错误"可加"剩余N次" | 加剩余次数提示 |
| 下单-库存不足 | 边界 | ✅ | 提示库存不足 | 清晰但无替代建议 | 建议补货提醒 |
## 优化建议(按优先级)
1. 🔴 登录失败应限制重试次数并提示(安全+体验)
2. 🟡 下单库存不足建议补充替代商品推荐
3. 🟢 列表接口返回字段过多,建议精简
## 体验结论
- 覆盖分支:X / 总 Y
- 正确性:全通过
- 体验质量:良好 / 需优化
- 负面路径反馈:{整体评价}
何时不使用动态体验
- 对应 e2e 场景未通过 → 先修 e2e,不进入体验。
- 代码尚未实现 → 无从规划体验路径。
- 只需验证单接口连通性 → 用
api-testing。
体验产物落盘
动态体验不落盘代码(区别于断言式 e2e),但体验计划、体验记录、体验报告需落盘供复盘与追踪。统一存于 tests/e2e/experience/(与 e2e 断言产物同根目录、独立子目录隔离):
tests/e2e/experience/ # 动态体验产物根目录
├── plans/ # 体验计划(白盒规划产物,每批一份)
│ └── 2026-08-06-login-batch1.md
├── records/ # 体验结果记录(黑盒执行产物,对应各批)
│ └── 2026-08-06-login-batch1-records.md
└── reports/ # 体验报告(全部批次完成后的汇总)
└── 2026-08-06-login-experience.md
- 体验计划(
plans/):D1 产出,每批一份,含体验点清单(分支/路径类型/动作/预期),供执行对照与复盘。 - 体验记录(
records/):D2 产出,对应各批,记录每个体验点的实际观察与四维评估。 - 体验报告(
reports/):D4 产出,全部批次完成后的汇总(前置门禁/体验范围/明细/优化建议/体验结论)。 - 命名规范:
{YYYY-MM-DD}-{功能slug}-{批次/类型}.md(kebab-case,同项目文档命名约定)。 - 安全提示:凭证脱敏同 e2e——体验记录/报告中只存脱敏前缀,不落完整 token。
常见陷阱
- 忘记
produces/depends_on:下游${ctx.x}解析失败 → 每个产出 step 必须声明produces,消费方必须depends_on上游。 - 把 e2e 当单元测试写:e2e 验证真实副作用与跨组件终态,不要 mock 内部依赖。
- 异步未用
wait:下单后库存扣减是异步的,直接db校验会偶发失败 → 用wait轮询。 - 生产环境误操作:指向生产时务必强告警 + 危险操作确认;优先在非生产环境跑。
- 凭证泄露:报告/日志只存脱敏前缀,不要把完整 token 写进
ctx.data或文件。 - teardown 缺失:有真实创建就必须有对称清理,否则污染测试数据。
- e2e 与单测混目录:e2e 产物必须放
tests/e2e/并配置单测排除,否则被单测 CI 误跑、污染隔离假设。 - 定义里硬编码密钥/URL:测试定义文件禁止内联真实 secret/endpoint,一律
${ENV.XXX}引用 + env 文件(.env.e2e优先,回退.env)注入。 - 断言迎合代码实现:e2e 是黑盒验收,断言对照需求/设计规格(只看入参→返回),不要依据代码内部逻辑写断言。
- 动态体验跳过前置门禁:e2e 未通过就做体验 → 基本正确性没保证,体验结论无意义;必须 e2e 先 PASS。
- 白盒越界写判据:动态体验读代码只为规划覆盖路径,若执行时依据代码内部逻辑判断对错 → 破坏黑盒体验根基。
- 负面路径做真实破坏:故意错误操作仅限只读/可回滚(输错密码、非法参数),不得借负面路径真实删除/破坏数据。
- 体验计划不分批:代码庞大时一次性规划全部 → 易遗漏且难确认;应分批创建计划、执行确认后再下一批。
更多资源
- 各 Step 类型完整契约、Context 解析、安全门禁细节:reference.md
- 完整示例旅程(注册下单 + UI 混合):examples.md
- HTTP API 步骤约定来源:
use_skill("api-testing")