对真实运行系统执行端到端验证。按业务旅程编排多类型步骤,通过跨步骤共享状态串联,验证跨组件最终一致状态。当用户要求"跑一遍完整流程看看对不对""真实链路测试""端到端验证""全链路验证""检查跨系统终态""验收测试""acceptance test"时使用。
Scanned 9/20/2026
Install to Claude Code
npx -y skills add HACK-WU/skills --skill e2e-testing --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of E2e Testing?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/hack-wu-e2e-testing)More formats (shields.io, HTML) on the badges page.
---
name: e2e-testing
description: 对真实运行系统执行端到端验证。按业务旅程编排多类型步骤,通过跨步骤共享状态串联,验证跨组件最终一致状态。当用户要求"跑一遍完整流程看看对不对""真实链路测试""端到端验证""全链路验证""检查跨系统终态""验收测试""acceptance test"时使用。
---
# 端到端真实操作测试(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 检查即可,无需完整旅程编排
- **只做静态验证**(格式 / 配置 / 规则检查)→ 用对应专项工具,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`),互不影响。
- **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`:
```yaml
- 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}` 引用。具体用哪些类型由**被测功能**决定(不预设固定集)。
### 阶段 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`)已文档化的规范:
1. **响应结构**:归一化为 `{ result: bool, code: int, message: str, data: any }`;失败也返回结构不抛异常。
2. **业务断言**:不仅看 `code`,还要校验 `data` 的**字段存在性 / 类型 / 取值**(可取嵌套 `data.user.name`)。**仅借鉴该断言思路**(校验 data 而非只看 code),具体 HTTP 客户端由被测项目的工具决定,**不强依赖 httpflex**——可用的库都可(项目自有客户端、requests、httpx 等),只要产出归一化的 `{result,code,message,data}` 结构供本技能做 `assert` 即可。
3. **凭证脱敏**:token/cookie 只显前缀,不回显完整凭证。
4. **报告风格**:明细表 + 失败根因,与本技能 journey 报告对齐。
> 若项目已用 httpflex-py,可直接照搬 `api-testing/reference.md` 的客户端模板生成 `api` 步骤客户端;否则按项目既有方式发请求,只需遵循上述响应结构与业务断言约定。本技能只负责编排与状态流转,不绑定具体 HTTP 实现。
## 报告模板(Journey 级)
```markdown
# 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。
### 体验报告
```markdown
# 动态体验报告:{功能/模块名}
## 前置门禁
- 对应 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](reference.md)
- 完整示例旅程(注册下单 + UI 混合):[examples.md](examples.md)
- HTTP API 步骤约定来源:`use_skill("api-testing")`
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!