test-generator
Use when a feature, API, bug fix, refactor, release gate, or risky code path needs behavior-focused tests, a justified test level, regression proof, executable evidence, or an explicit account of test
SKILL.mdtest-generator/SKILL.md
GitHub风险驱动测试生成器
中文简介
风险驱动测试生成器将行为、失效后果和现有项目约定转成可运行的测试矩阵、最小可信 fixture、可维护断言与命令证据。它不把覆盖率百分比、快照数量或 mock 调用次数当作质量结论;测试必须能观察用户、调用方或相邻系统真正依赖的行为。
使用背景
新增 API、修复 Bug 或调整既有逻辑时,常见的失败不是“没有测试”,而是测试选错层级、只验证内部调用、用过度 mock 隐藏错误,或让快照替代状态与契约验证。Bug 修复尤其容易在修复后才写一个立刻通过的测试,无法证明它曾捕获原始问题。本 Skill 让测试选择与风险、故障模式和可观察行为绑定,并保留真实命令结果与尚未覆盖的边界。
核心原则
- 从可观察行为和失效风险出发;覆盖率只能是诊断信号,不能替代行为证据。
- 用能揭示风险的最低测试层级;只有跨边界行为无法在低层可靠证明时才上移到集成、契约或 E2E。
- Bug 回归测试在修复前必须红灯且失败原因与原始症状一致;做不到时如实记录原因和可复核替代证据,不把绿灯称为回归证明。
- fixture 表达真实、最小的业务状态;mock 只替换不属于被测责任的慢、不稳定、昂贵或不可控边界,且不能伪造被测行为。
- 断言稳定的输出、状态转换、副作用或契约;不用整页快照、实现细节、时间偶然值或无业务含义的调用次数制造安全感。
- 每项“已验证”必须附工作目录、完整命令、时间、退出码、关键输出与证据 ID;未运行和失败同样保留。
适用场景
- 为新增接口、用户流程、状态转换、权限规则、数据迁移或外部集成补测试。
- 为已定位的 Bug 增加先失败的回归测试,并覆盖根因不变量和未受影响对照。
- 评估现有测试是否只提供浅层覆盖,制定重构前的特征化测试或发布门禁。
- 需要在单元、组件、集成、契约、E2E、属性测试和人工验证之间做可解释取舍。
不适用场景
- 未知目标行为、调用方或风险时,先澄清验收标准;不要凭文件名生成测试。
- Bug 的症状、复现、影响或环境仍不清楚时,先用
bug-debugging-playbook建立证据链;不能把猜测的测试当作根因。 - 需要实现整个需求或处理工作区/提交边界时,使用
issue-to-pr;本 Skill 只交付测试设计、实现建议和验证证据。 - 只要求提高覆盖率阈值而没有行为、故障成本或关键路径时,拒绝把百分比当作完成标准,转而索取风险与验收信息。
输入要求
将来源与不确定性保留为 [事实]、[推断]、[假设] 或 [未知],不可补造仓库事实。
- 行为与验收:调用者/用户、前置状态、输入、可观察结果、失败结果、非目标与兼容要求。
- 风险:错误影响、数据/资金/安全敏感性、频率、可恢复性、并发/幂等、权限和外部边界。
- 代码与契约:入口、责任边界、输入输出 schema、状态机、事件、副作用、依赖和相邻调用方。
- 现有测试约定:框架、命令、目录、测试层级、fixture 工具、mock/server 工具、时钟/随机数约束和 CI 门禁。
- Bug 专属证据:修复前版本或可重现环境、最小步骤、期望/实际、失败信号、成功对照和根因不变量。
- 执行限制:允许的环境、测试数据与脱敏规则、网络/服务访问、运行预算、不可模拟依赖和人工验证 owner。
信息不足时的处理
- 行为或验收缺失: 输出澄清问题、可搜索入口和停止条件;不编造断言、测试文件或命令。
- 测试约定未知: 先只读检查相邻测试、脚本与 CI;输出候选层级及选择条件,不假设 Jest、pytest 或目录结构。
- Bug 无法在修复前运行: 不称“回归测试已证明”。记录无法红灯的具体原因、已尝试命令/版本/环境,并使用原始复现日志、保留的失败工件、修复前可执行版本、生产合成探针或人工脚本之一作为标注为
[替代证据]的证据;说明它不能替代自动化红灯以及恢复红灯所需条件。 - 外部系统不可控: 只 mock 该边界,保留请求/响应/超时/错误的契约测试或 provider 验证;若连契约也不可得,标记集成缺口。
- 并发、时钟或随机性不可控: 注入时钟、调度器、随机源或可控队列;若项目不能控制,设计重复/隔离运行和可观察不变量,并披露不稳定风险。
工作流
- 建立测试卡。 记录行为、调用方、风险、验收、非目标、来源和未知;将每个可观察结果分配
B-*,将故障模式分配R-*。 - 阅读本地约定和相邻责任。 确认入口、调用链、已有测试、fixture、mock 边界、命令和 CI;只引用实际读到的路径与规则。
- 映射风险到测试层级。 对每个
R-*选择最低有效层级,并写清为什么单元测试不足、为什么不需要 E2E,见下表和模板。 - 枚举状态和边界。 对每个
B-*列主路径、空值/上限/格式/排序、错误分类、权限矩阵、重试/幂等/竞态、版本兼容和跨服务契约;明确哪些不适用。 - 设计 fixture 与 mock。 fixture 只保留触发行为的业务事实和成功对照;注明数据来源、隔离/清理、时间与随机数控制。为每个 mock 写边界、真实契约、不能断言的内容和替代集成验证。
- 先写失败证明。 功能新增时先让新验收测试因缺失行为失败。Bug 修复时在修复前版本或撤销修复的受控副本运行
RED-*,确认失败信号是原始症状而非测试/fixture 故障;不能红灯时执行“信息不足”分支并保留证据。 - 实现并保持断言可维护。 每个测试只验证一个风险相关的结果;优先语义查询、业务值、持久化状态、事件 payload 或公开响应。避免快照整棵树、私有函数、CSS 类名和无意义的 mock 次数。
- 运行分层验证。 先运行针对
B-*/R-*的最小测试,再运行受影响相邻套件、类型/构建/契约或 E2E 中适用项。记录T-*命令证据和实际结果。 - 交付缺口与门禁。 将未覆盖风险按影响、原因、缓解、owner 和下一步列出;明确结论为通过、有条件通过或不通过,绝不以覆盖率数字掩盖缺口。
专业判断规则
风险到测试层级映射
| 风险或行为 | 首选层级 | 上移条件 | 关键断言 | 不可替代的证据 |
|---|---|---|---|---|
| 纯规则、转换、状态机分支 | 单元 | 实际依赖的序列化/持久化改变结果 | 输入到公开结果或状态转换 | 边界值与未受影响分支 |
| 组件反馈、键盘/无障碍、加载/错误状态 | 组件 | 路由、真实授权或跨页面协作决定行为 | 用户可见语义、可操作性、状态恢复 | 空/错误/禁用状态 |
| 数据库、队列、缓存、多个模块协作 | 集成 | 真实部署拓扑、第三方或浏览器协议决定风险 | 持久化、副作用、事务/回滚、错误映射 | 隔离数据与清理 |
| consumer/provider 数据格式与错误语义 | 契约 | 无法在本地模拟协议版本或认证 | schema、必填/可选、错误码、版本兼容 | provider 或 consumer 校验 |
| 关键用户旅程、认证链、浏览器/部署配置 | E2E | 只为凑“端到端”而重复低层行为时不上移 | 用户完成目标与关键失败恢复 | 稳定环境、可控数据 |
| 并发、幂等、重试、时序 | 单元加集成 | 真实锁、事务或队列语义不可模拟 | 一次副作用、顺序、不变量、取消/超时 | 可控调度或真实隔离边界 |
| 难以自动化的视觉、设备或第三方限制 | 人工/合成验证 | 能建立稳定自动化时必须替换 | 观察步骤、样本、阈值、owner | 时间戳工件与自动化缺口 |
- 测试层级由失效发生的边界决定,不由“金字塔”口号或文件类型决定;同一
B-*可以有低层规则测试和一个跨边界保护测试,但不得重复堆叠。 - 覆盖率可指出未执行代码,却不能证明异常语义、权限隔离、并发不变量或用户完成任务;不以“达到 N%”作为通过条件。
- 快照只可用于有意审查、稳定且难以用语义断言表达的序列化/渲染契约,必须审查其差异并配合行为断言;大而无语义的 UI 快照不计入风险覆盖。
Bug 回归、边界和断言
RED-*必须写修复前 commit/环境、完整命令、退出码、期望失败信号和实际摘要;因依赖、语法、fixture 或环境崩溃的失败不算证明。GREEN-*回链对应RED-*,并验证根因不变量与一个成功对照。无法红灯的ALT-*只能证明历史症状或环境限制,不能替代RED-*。- 每个风险至少判断:边界/空状态、可恢复和不可恢复错误、权限拒绝与越权、并发/重试/幂等、输入或事件契约兼容。明确“不适用”的机制依据。
- 断言面向公开 API、可访问名称、业务字段、可观测副作用或稳定协议;不要断言内部 helper、组件树结构、实现顺序或 mock 调用总数,除非调用次数本身是公开限流/幂等契约。
Fixture 与 mock 边界
- fixture 必须包含最小真实领域关系和成功对照,避免共享可变全局数据、生产个人数据和不透明大对象;每例独立、可重放并清理副作用。
- mock 不得返回被测模块应计算的结果,也不得把认证、校验、重试或错误映射全部短路。被 mock 的网络、时钟、随机数、邮件等边界必须另有契约、集成或人工证据。
- 对外部副作用使用 fake server、事务、临时数据库、沙箱账户或记录/回放时,写明真实性、隔离性、过期条件和 refresh owner。
输出契约
按 references/templates.md 交付;缺失内容保留状态,不以空白代替:
- 测试卡:
B-*行为、调用方、验收、事实/推断/假设/未知和停止条件。 - 风险驱动矩阵:
R-*、失效后果、层级选择、边界/错误/权限/并发/契约、测试和不适用理由。 - fixture 与 mock 边界:数据、隔离、控制源、mock 契约、未覆盖边界和替代验证。
- 测试用例与断言:前置、动作、稳定观察、反例、成功对照和对应
B-*/R-*。 RED-*/ALT-*/GREEN-*/T-*证据账本:目录、命令、时间、退出码、关键输出、结果与关联。- 覆盖缺口与结论:风险、影响、缓解、owner、恢复条件和通过/有条件通过/不通过。
质量门槛
- 每个测试至少回链一个
B-*或R-*;没有可观察结果的测试不计入完成。 - 高影响行为不能只靠快照、浅层渲染、mock 调用次数或覆盖率数字证明。
- Bug 的自动化回归结论必须有有效
RED-*与回链GREEN-*;缺红灯时结论最多为有条件通过并列出ALT-*限制。 - 关键风险必须评估边界、错误、权限、并发和契约;未测不是默认安全,必须列入缺口。
- fixture 与 mock 的边界、隔离与无法证明的部分必须可审查;不得以 mock 成功代替真实边界的验证。
- “已通过”只能引用真实
T-*/GREEN-*命令结果;无命令、失败或未运行时如实降级结论。
常见失败与修正
| 失败 | 修正 |
|---|---|
| 为新 API 写 controller 单测,却没验证持久化和错误码 | 将规则留在单元,将事务/错误映射放入集成;对调用方协议加契约断言。 |
| 修复后才写一个通过的回归测试 | 在修复前版本或受控撤销副本运行 RED-*;无法运行则记录 ALT-* 与恢复红灯条件。 |
| 用全页快照或 90% 覆盖率宣布质量足够 | 回到 B-*/R-*,补可观察的错误、权限、并发或契约断言;覆盖率只做辅助诊断。 |
| mock 数据库、认证和网络后只断言调用次数 | 保留被测责任,使用临时真实边界或契约测试;只有限流/幂等本身才断言次数。 |
| 并发测试依赖睡眠和偶然顺序 | 注入时钟/调度器或使用可控队列,断言一次副作用、顺序和取消不变量。 |
| 测试失败但来自 fixture 拼错或环境启动失败 | 修复测试支撑并重新运行;该失败不进入 RED-* 账本。 |
参考资料
references/usage-guide.zh.md:准备输入、调用方式、输出阅读与上下游衔接。references/templates.md:测试卡、风险矩阵、fixture/mock、红绿证据和缺口模板。references/checklists.md:输入、风险、断言、证据与交接的通过判定。references/examples.md:新增 API、已修复 Bug 与覆盖率导向请求的三个场景。