Back to skills
SKILL.md
E2e Testing
ASecurity对真实运行系统做端到端验证:按业务旅程编排步骤、跨步骤共享状态,验证跨组件最终一致状态。触发:"跑一遍完整流程看看对不对"、"真实链路测试"、"端到端验证"、"全链路验证"、"检查跨系统终态"。
- 2 stars
- 0 votes
- 0 copies
- 2 views
- Added September 20, 2026
Works with
Security analysis
100/100Pro scans all 3 files and shows the line behind each finding
npx -y skills add HACK-WU/skills --skill e2e-testing --agent claude-codeAre you the author of E2e Testing?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/hack-wu-e2e-testing)---
name: e2e-testing
description: 对真实运行系统做端到端验证:按业务旅程编排步骤、跨步骤共享状态,验证跨组件最终一致状态。触发:"跑一遍完整流程看看对不对"、"真实链路测试"、"端到端验证"、"全链路验证"、"检查跨系统终态"。
---
# 端到端真实操作测试(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`),互不影响。
- **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}` 引用。具体用哪些类型由**被测功能**决定(不预设固定集)。
- **有索引时先用**(挑关键路径 + 定终态校验点):仓库已建 `.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`)已文档化的规范:
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")`
Files in this skill
- SKILL.md
- examples.md
- reference.md
Attribution
Related skills
View all in testing →Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.