关于 test-evidence-review
面向 Claude 的 Skill,用于审核故事中的自动化测试与人工 QA 证据,并按项目门槛评估覆盖度和质量。它可在 QA 移交或里程碑审查前报告结论与缺口。
主要功能
- 01可配置阻断与建议门槛
- 02自动化测试质量审核
- 03人工证据与签署检查
- 04按故事、冲刺或系统审核
- 05对话摘要及可选报告
适用场景
- 01QA 移交前审计测试覆盖
- 02审核整个冲刺的证据
- 03检查故事关闭准备情况
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ donchitos/ claude-code-game-studios --skill test-evidence-review安装后在 Claude Code 中输入/test-evidence-review确认已加载。
详细介绍
!bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation,workflow,qa.level,testing.strict
自动化模式:解析 modes.automation(project.local.yaml →
project.yaml → 默认值 collaborative)。每次 AskUserQuestion 调用和
每次文件写入都遵循 .claude/docs/automation-modes.md
(collaborative 始终提问 · guided 仅在重大事项上提问 · autonomous 记录并继续;
automation_always_ask 类别始终提示)。
qa.level 和 testing.strict(已在上方解析)决定本次审查可将哪些问题
判定为阻塞项——/story-done 按相同规则关闭故事,因此此处的阻塞项会阻止
/story-done:
qa.level: minimal可免除测试。Logic、Integration 或 Config/Data 故事 没有测试证据(对于 Config/Data,没有冒烟报告)时,标记为WAIVED (qa.level: minimal)——而非 MISSING——且不会产生阻塞项;若确有测试, 仍需审查,但其中的缺口属于建议项。Visual/Feel 和 UI 证据(留存的截图及 Visual/Feel 签核)永不豁免。- 按故事类型确定门槛级别:从解析后的配置块中读取
testing.strict.<type>(Logic→logic、Integration→integration、Visual/Feel→visual、 UI→ui、Config/Data→config):true→ 阻塞,false→ 建议,未设置时, 使用适用于所有类型的纯布尔值testing.strict: true|false(旧格式);否则使用.claude/docs/coding-standards.md中的默认门槛级别(Logic、Integration、 Visual/Feel 和 UI 为阻塞;Config/Data 为建议)。以下所有“阻塞”均指该故事 类型的门槛级别。
测试证据审查
/smoke-check 会验证测试文件是否存在且通过。本技能更进一步——审查这些
测试和证据文档的质量。即使测试文件存在且通过,仍可能未覆盖关键行为。即使手动
证据文档存在,也可能缺少结项所需的签核。
**输出:**摘要报告(在对话中)+ 可选的 production/qa/evidence-review-[date].md
运行时机:
- QA 交接签核前(
/team-qa第 5 阶段) - 对任何测试质量存疑的故事
- 作为里程碑审查的一部分,审计 Logic 和 Integration 故事质量
1. 解析参数
模式:
/test-evidence-review [story-path]— 审查单个故事的证据/test-evidence-review sprint— 审查当前 Sprint 中的所有故事/test-evidence-review [system-name]— 审查某个 epic/system 中的所有故事- 不提供参数 — 询问范围:“单个故事”、“当前 Sprint”或“某个系统”
2. 加载范围内的故事
根据参数:
单个故事:直接读取故事文件。提取:故事类型、测试证据部分、 故事标识、系统名称。
Sprint:读取 production/sprints/ 中最近修改的文件;从 Sprint 计划中
提取故事文件路径列表。
系统:对 production/epics/[system-name]/story-*.md 使用 glob。
如果解析出的范围内没有任何故事,请在此处停止。 报告
NOT ASSESSED — no stories in scope,说明搜索的范围和为空的路径,并给出后续操作:没有 Sprint 文件 →/sprint-plan new(在workflow: minimal中,该工作流没有 Sprint,改用/test-evidence-review [epic-slug]);Sprint 计划 中未列出故事 →/create-stories [epic-slug];[system-name]glob 没有匹配项 → 指明该 glob。不要继续到第 3 节。要检查空范围,而不只是逐个故事的未知状态。 此处的判定 词汇——ADEQUATE / INCOMPLETE / MISSING——需要一个“无法检查”值,否则无法验证的故事 会得到一个声称有人已核验的判定;
NOT ASSESSED就是为此而设。但为逐个故事的未知状态 找到归属,并不能解决空范围的未知状态。 没有故事时, 第 6 节报告会生成一个空的摘要表,并以BLOCKING items: 0 / ADVISORY items: 0结尾——这会让人以为所有内容都已审查, 一切正常。此技能用于把关故事关闭,而coding-standards.md将 Logic、 Integration、Visual/Feel 和 UI 证据标记为 BLOCKING,因此错误地报告一切正常,就会关闭无人 审查过的故事。
对于最终得到的故事集合,使用针对性的章节 grep,而不是完整读取每个故事,收集以下字段:
Grep pattern="## Test Evidence" glob="production/epics/**/story-*.md" output_mode="content" -A 8
Grep pattern="## Acceptance Criteria" glob="production/epics/**/story-*.md" output_mode="content" -A 15
- 故事类型(Logic / Integration / Visual/Feel / UI / Config/Data)以及
声明的证据路径——两者都位于
## Test Evidence下,因此第一个 grep 的-A 8可以捕获它们。 - 验收标准列表——第二个 grep 中的
## Acceptance Criteria区块。 - 故事标识(来自文件名)和系统(来自目录路径)——无需读取。
仅当故事缺少
Test Evidence部分或内容不明确时,才完整读取故事。 (在 Sprint 模式下,将 glob 范围限定为 Sprint 计划中的故事路径。)
3. 定位证据文件
对于每个故事,查找其证据。首先检查故事中声明的证据路径
——即第 2 节从其 ## Test Evidence 部分获取的路径。若该路径存在,就使用
它。仅在未声明路径或找不到该路径时,才改为搜索:
Logic 故事:搜索引擎的单元测试根目录——tests/unit/[system]/
(Godot)、Assets/Tests/EditMode/(Unity)、Source/<Module>/Private/Tests/
(Unreal);参见 .claude/docs/directory-structure.md——查找文件名
包含故事标识或系统名称的文件。测试文件的命名遵循
.claude/rules/test-standards.md,不一定是 [story-slug]_test.*。
Integration 故事:在相同的集成测试根目录下查找(tests/integration/[system]/、
Assets/Tests/PlayMode/ 或 Unreal 的测试根目录)
- 还要检查
production/qa/playtests/中提及该故事的试玩记录
Visual/Feel 和 UI 故事:对 production/qa/evidence/ 使用 glob,查找属于该故事的留存图片
(*.png、*.jpg、*.gif),以及
[story-slug]-evidence.*
Config/Data 故事:对 production/qa/smoke-*.md 使用 glob(任意冒烟检查报告)
记录每个故事找到的内容(路径)或未找到的内容(缺口)。
4. 审查自动化测试质量(Logic / Integration)
对于找到的每个测试文件,读取并评估:
断言覆盖率
统计不同断言的数量(包含 assert、expect、check、verify 或引擎专用断言模式的代码行)。断言数量较低是质量信号——如果每个测试函数只做 1 项断言,可能无法覆盖预期行为的范围。
阈值:
- 每个测试函数有 3 项或更多断言 → 正常
- 每个测试函数有 1–2 项断言 → 标注为可能覆盖不足
- 0 项断言(测试存在,但没有断言)→ 标记为 BLOCKING(该故事类型的门槛级别;
qa.level: minimal时为 ADVISORY)——测试会空通过,无法证明任何内容
边界情况覆盖率
对于故事中包含数字、阈值或“当 X 发生时”条件的每项验收标准:检查测试函数名称或测试正文是否提到了该特定情况。
启发式方法:
- 在测试文件中搜索 "zero"、"max"、"null"、"empty"、"min"、"invalid"、 "boundary"、"edge"——出现其中任意一项都是正向信号
- 如果故事有包含具体边界值的 Formulas 部分:检查测试是否至少覆盖最小值和最大值
命名质量
测试函数名称应描述:场景 + 预期结果。
各引擎的命名模式(.claude/rules/test-standards.md):Godot
test_[scenario]_[expected],Unity [Scenario]_[Expected],Unreal
<Project>.[System].[Scenario]。
将名称笼统的函数(如 test_1、test_run、testBasic)标记为命名问题——这类名称会让故障更难诊断。
公式可追溯性
对于 GDD 有 Formulas 部分的 Logic 故事:检查测试文件中是否至少有一项测试的名称或注释提到了公式名称或公式值。如果测试覆盖了某个公式,却没有按名称提及它,那么公式变更后会更难维护。
5. 检查人工证据质量(视觉/手感 / UI)
对于找到的每份证据文档,阅读并评估以下检查项。
UI 故事不需要证据文档。 如果没有文档,其保留的截图就是证据:只检查截图 / 产物是否完整(故事更改的每个屏幕都要有一张图片——验收标准中仅导航到的屏幕,例如退出后显示的标题屏幕,不需要单独提供截图)以及日期覆盖情况(图片的日期)。在这两项上,UI 故事即为 ADEQUATE;绝不能仅因缺少文档、未关联验收标准或没有签核而判为 INCOMPLETE。
验收标准关联
证据文档应引用故事中的每项验收标准。 检查:证据文档是否包含每项标准(或清晰转述)?缺少的标准意味着从未得到验证。
签核完整性
故事的结项方式遵循
.claude/docs/coding-standards.md 中的证据表——/story-done 在所有
qa.level 下都应用相同规则:
- Visual/Feel:证据文档(使用 test-evidence 模板)中的每一行签核都必须标为
[x] Approved。空白或缺失的行都属于 INCOMPLETE。 - UI:不要求签核——保留的截图即可结项。如果有签核,请注明;绝不能仅因缺少签核而将 UI 故事标为 INCOMPLETE。
截图 / 产物完整性
对于 Visual/Feel 故事:在 production/qa/evidence/ 中查找属于该故事的保留图片(*.png、*.jpg、*.gif)。描述了视觉检查却没有保留图片的文档属于 INCOMPLETE——默认情况下,此门槛为 BLOCKING;描述只是断言,并非证据。
对于 UI 故事:同样要求保留所涉及每个屏幕的截图。欢迎提供操作过程日志,但并非必需。
证据早于代码
对于保留了图片的每个故事,运行
bash .claude/scripts/review-receipts.sh check production/qa/evidence/[story-slug]/stamp.txt。
将每个 CHANGED: 或 GONE: 文件列为 POTENTIALLY STALE——这些文件在证据采集后发生了变化。RECEIPT: NONE:注明“无时间戳文件”,并使用下方的日期检查。
报告中仅有一行:它永远不会改变故事的判定结果。
日期覆盖范围
证据文档应注明日期。如果日期早于故事的最后一次重大变更(启发式判断:与冲刺计划中的冲刺开始日期比较),则标记为 POTENTIALLY STALE——证据可能未覆盖最终实现。
6. 编写审查报告
为每个故事指定一个判定:
| 判定 | 含义 |
|---|---|
| ADEQUATE | 测试/证据存在,通过质量检查,覆盖所有验收标准 |
| INCOMPLETE | 测试/证据存在,但存在质量缺陷(断言过少、缺少签字确认) |
| MISSING | 对于当前 qa.level 要求提供测试或证据的故事类型,未找到任何测试或证据 |
| NOT ASSESSED | 无法审查此故事——见下文 |
| WAIVED (qa.level: minimal) | qa.level: minimal 时,没有测试证据的 Logic、Integration 或 Config/Data 故事——测试并非必需,因此没有缺失项;将其标记为已豁免 |
必须使用
NOT ASSESSED,它不是较轻的MISSING。 其他三种判定都假定审查确实已执行。MISSING表示 我检查过,但什么也没找到——这是一个真实且可报告的失败。绝不能将其用于 我无法检查,因为这根本不是关于故事的调查结果。遇到以下情况时使用NOT ASSESSED:
- 无法确定故事类型,因此不知道所需的证据是什么(
.claude/docs/coding-standards.md中的类型→证据映射,是其他任何判定具有意义的前提);- 已指定证据路径,但无法读取或超出本次运行的范围;
- 无法解析故事文件本身。
逐个故事说明属于上述哪种情况。 仅写一个
NOT ASSESSED,读者无法据此采取行动;将它与MISSING区分开来的意义,正是两者需要不同的修复措施:一种需要编写测试,另一种需要让审查者获得访问权限或对故事进行分类。
整体冲刺/系统判定取决于其中最差的故事判定,并且 NOT ASSESSED 的优先级高于 ADEQUATE:如果无法评估部分审查范围,就不能确认整个范围符合要求。它的优先级不高于 INCOMPLETE 或 MISSING——已知的失败比未知情况更容易采取行动,将真实失败排在访问问题之后会掩盖它。WAIVED 的优先级低于 ADEQUATE:只有当范围内的每个故事都已豁免时,整体判定才为 WAIVED;无论如何,报告都要列出每个已豁免的故事。
为什么这很重要:证据审查会阻止故事完成,而
coding-standards.md将 Logic、Integration、Visual/Feel 和 UI 证据列为阻塞项。如果判定体系没有办法表达“我无法检查”,每一种未知情况就只能被归入三种关于故事的说法之一——这正是未经过任何人验证的故事,却被赋予了仿佛有人验证过的判定的原因。
## Test Evidence Review
> **Date**: [date]
> **Scope**: [single story path | Sprint [N] | [system name]]
> **Stories reviewed**: [N]
> **Overall verdict**: ADEQUATE / INCOMPLETE / MISSING / NOT ASSESSED / WAIVED
> **qa.level**: [minimal | standard | full] — **testing.strict**: [the resolved per-type values, or "unset — coding-standards.md defaults"]
---
### Story-by-Story Results
#### [Story Title] — [Type] — [ADEQUATE/INCOMPLETE/MISSING/NOT ASSESSED/WAIVED]
**Test/evidence path**: `[path]` (found) / (not found)
**Automated test quality** *(Logic/Integration only)*:
- Assertion coverage: [N per function on average] — [adequate / thin / none]
- Edge cases: [covered / partial / not found]
- Naming: [consistent / [N] generic names flagged]
- Formula traceability: [yes / no — formula names not referenced in tests]
**Manual evidence quality** *(Visual/Feel/UI only)*:
- Criterion linkage: [N/M criteria referenced]
- Lead sign-off: [✓ approved | ✗ missing | deferred — reason] *(Visual/Feel only; a UI story needs none)*
- Artefacts: [screenshots present / missing / N/A]
- Freshness: [dated [date] — current / potentially stale]
**Issues**:
- BLOCKING: [description] *(prevents story-done)*
- ADVISORY: [description] *(should fix before release)*
---
### Summary
| Story | Type | Verdict | Issues |
|-------|------|---------|--------|
| [title] | Logic | ADEQUATE | None |
| [title] | Integration | INCOMPLETE | Thin assertions (avg 1.2/function) |
| [title] | Visual/Feel | INCOMPLETE | Lead sign-off missing |
| [title] | Logic | MISSING | No test file found |
| [title] | Logic | WAIVED | No test — waived at `qa.level: minimal` |
**BLOCKING items** (must resolve before story can be closed): [N]
**ADVISORY items** (should address before release): [N]
7. 编写输出(可选)
在对话中展示报告。
询问:“可以将这份测试证据审查写入
production/qa/evidence-review-[date].md 吗?”
这是可选步骤——报告单独使用也很有价值。只有用户希望保留记录时才写入。
报告之后:
- 对于阻塞项:“必须先解决这些问题,
/story-done才能将故事标记为 Complete。现在要处理其中任何一项吗?” - 对于断言过少的情况:“可以运行
/test-helpers [system],查看常见场景的脚手架断言模式。” - 对于缺少签字确认的情况:“需要由 [role] 进行人工签字确认。将
[evidence-path]分享给他们以完成签字确认。”
判定:COMPLETE——证据审查已完成。如果发现阻塞项,则使用 CONCERNS。
协作协议
- 报告质量问题,不要修复问题 — 此技能用于读取和评估;它不会修改测试文件或证据文档
- “足够”意味着足以发布,而非完美 — 对于运行正常且足够全面、能够带来信心的测试,避免挑剔
- 区分“阻塞”和“建议”很重要 — 只有当缺口导致故事验收标准确实未经验证时,才标记为“阻塞”
- 写入前先征求同意 — 报告文件是可选的;写入前务必确认