mcpField
T
test-flakiness

test-flakiness

github.com/donchitos测试与质量28.5k445 次安装1 周前更新
代码仓库

关于 test-flakiness

面向 Claude 的 Skill,通过分析多次运行的测试结果日志来识别和分类不稳定测试,并建议隔离、修复或监控。运行次数少于 3 次时,会将发现标为疑似。

主要功能

  1. 01分析 CI 与本地测试日志
  2. 02分类可能的不稳定原因
  3. 03按失败频率评估发现
  4. 04建议隔离、修复或监控
  5. 05经批准更新隔离清单

适用场景

  1. 01调查反复出现的 CI 失败
  2. 02评估回归审查标记的测试
  3. 03跟踪多次运行中的疑似不稳定项

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/donchitos/claude-code-game-studios --skill test-flakiness

安装后在 Claude Code 中输入/test-flakiness确认已加载。

详细介绍

!bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation

自动化模式:解析 modes.automation(project.local.yaml → project.yaml → 默认值 collaborative)。每次调用 AskUserQuestion 和 每次文件写入都遵循 .claude/docs/automation-modes.md (collaborative 始终询问 · guided 仅重大事项询问 · autonomous 记录后继续; automation_always_ask 类别始终提示)。

测试不稳定性检测

不稳定测试是指在代码没有任何更改的情况下,有时通过、有时失败的测试。不稳定测试在某些方面甚至比没有测试更糟——它们会让团队习惯于忽略 CI 红色运行结果,从而掩盖真实故障。此技能可识别不稳定测试,解释可能的原因,并建议是隔离还是修复每个测试。

输出: 更新 tests/regression-suite.md 的隔离部分 + 可选的 production/qa/flakiness-report-[date].md

运行时机:

  • 润色阶段(测试已运行多次;统计信号可靠)
  • 开发者开始把 CI 故障当作“可能是不稳定”而不予理会时
  • /regression-suite 识别出需要诊断的隔离测试后

1. 解析参数

模式:

  • /test-flakiness [ci-log-path] — 分析指定的 CI 运行日志文件
  • /test-flakiness scan — 扫描 .github/ 或标准日志输出目录中的所有可用 CI 日志
  • /test-flakiness registry — 读取现有 regression-suite.md 隔离部分,并为已知的不稳定测试提供修复指导
  • 不带参数 — 自动检测:如果可以访问 CI 日志,则运行 scan,否则运行 registry

2. 定位 CI 日志数据

选项 A — GitHub Actions(首选)

检查测试结果制品:

ls -t .github/ 2>/dev/null
ls -t test-results/ 2>/dev/null

对于 Godot 项目:GdUnit4 会在 reports/ 下输出兼容 JUnit 格式的 XML 结果(其默认报告文件夹为 res://reports/)。检查 reports/,以及你保存运行结果的任何 test-results/ 目录,查找 .xml 文件。

对于 Unity 项目:game-ci 测试运行器默认会将 NUnit XML 输出到 test-results/。

对于 Unreal 项目:自动化日志位于 Saved/Logs/。搜索 Result={Success} 和 Result={Fail}——每项测试都会输出 Test Completed. Result={<status>} (docs/engine-reference/unreal/current-best-practices.md,“命令行”)。

选项 B — 本地日志文件

如果提供了路径参数,直接读取该文件。

选项 C — 没有可用日志数据

如果未找到日志:

“未找到 CI 日志数据。要检测不稳定测试,此技能需要多次运行的测试结果历史记录。可选方案:

  1. 至少运行测试套件 3 次并收集输出日志
  2. 检查 CI 流水线输出,并将日志保存到 test-results/
  3. 运行 /test-flakiness registry,检查 tests/regression-suite.md 中已标记为不稳定的测试”

停止并询问用户要采用哪个方案。


3. 解析测试结果

对于找到的每个 CI 日志或结果文件,解析:

JUnit XML 格式(GdUnit4):

  • 搜索 <testcase name= 获取测试名称
  • 搜索 <failure 或 <error 以识别失败
  • 解析 classname 和 name 属性,获取完整测试标识符

NUnit XML 格式(Unity — /smoke-check 读取的 <test-run> 元素所在文件):

  • 每项测试都是一个 <test-case 元素;其 fullname 属性是标识符
  • 其 result 属性为 Passed、Failed、Inconclusive 或 Skipped (docs/engine-reference/unity/current-best-practices.md,“命令行”); 只有 Passed 和 Failed 会纳入历史记录

纯文本日志:

  • 搜索通过/失败模式:
    • Godot:测试名称附近的 PASSED / FAILED
    • Unreal:Result={Success} / Result={Fail}
    • Unity:Test passed / Test failed

建立表格:test_id → [run1_result, run2_result, run3_result, ...]


4. 识别不稳定测试

如果某个测试在没有代码变更的情况下,多次运行的结果历史中既出现 PASS,也出现 FAIL,则该测试为不稳定测试。

不稳定程度阈值:

  • 高度不稳定:超过 25% 的运行失败——立即隔离
  • 中度不稳定:5–25% 的运行失败——尽快调查并修复
  • 低度/疑似不稳定:1–5% 的运行失败——持续监控;也可能确实是罕见故障

运行次数少于 3 次时,无论失败率如何,所有发现都属于疑似不稳定。 两次运行中失败一次,看起来失败率是 50%,但这只是一个数据点:不要隔离该测试,将其标记为疑似不稳定,并询问是否有更多运行数据。 上述等级和隔离措施适用于运行次数达到 3 次及以上的情况。

对于每个不稳定测试,判定可能的原因:

原因分类
原因症状修复方向
时序/异步等待信号或计时器后失败;通过率与系统负载相关添加显式的等待/同步;避免基于时间的延迟
顺序依赖在特定其他测试之后运行时失败;单独运行时通过添加适当的设置/清理;确保测试相互隔离
随机种子间歇性失败且无明显规律;涉及 RNG传入显式种子;不要在测试中使用 randf()
资源泄漏在一次测试运行中越靠后越容易失败在 teardown 中修复清理逻辑;检查孤立节点(Godot)或对象释放(Unity)
外部状态先前测试遗留的文件、场景或全局状态存在时失败隔离测试与文件系统;使用内存 mock
浮点数在 == 0.5 之类的比较中失败使用 epsilon 比较(is_equal_approx、Assert.AreApproximately)
场景/预制体加载竞态场景尚未就绪时失败实例化后等待一帧;使用 await get_tree().process_frame

使用 Grep 检查测试文件中的时序调用、randf、全局状态访问或浮点数相等比较,以缩小可能原因的范围。


5. 建议采取的措施

对于每个不稳定测试:

隔离(高度不稳定):

“立即隔离此测试。使用引擎自身的机制跳过该测试,在 tests/regression-suite.md 的隔离部分记录该测试,并在移除隔离前修复根本原因。”

按引擎选择跳过机制——只列出项目所用引擎对应的机制:

  • Godot(gdUnit4)、GDScript:在测试函数上使用跳过参数 — func test_x(_do_skip := true, _skip_reason := "flaky: [cause]")。gdUnit4 会在 addons/gdUnit4/src/core/GdUnitTestSuiteScanner.gd 中读取参数名 do_skip 和 skip_reason(允许带前导 _);此行为适用于 gdUnit4 6.2.2; 请在已安装版本的对应文件中确认。
  • Godot(gdUnit4)、C#:无法从源码核实 — gdUnit4 的 C# 测试特性不在 addons/gdUnit4/ 源码中,且 docs/engine-reference/godot/ 未涵盖这些特性。请在隔离部分记录,并询问用户如何跳过其 C# 测试;不要臆造特性。
  • Unity(NUnit):[Ignore("flaky: [cause]")] — NUnit 3 要求提供原因
  • Unreal:无法从源码核实 — docs/engine-reference/unreal/ 未说明如何跳过自动化测试。请在隔离部分记录,并询问用户如何在其 CI 中排除某个测试;不要臆造标记。

尽快调查并修复(中度):

“此测试间歇性地不可靠。可能的根本原因是 [cause]。 建议的修复:[根据原因分类提出具体修复方案]。暂时不要隔离——直接修复测试。”

监控(低度/疑似不稳定):

“此测试显示出疑似不稳定。隔离前请收集更多运行数据。在回归套件中将其标记为‘疑似’。”


6. 生成报告

对话摘要
## Flakiness Detection Results

**Runs analysed**: [N]
**Tests tracked**: [N]

### Flaky Tests Found

| Test | System | Fail Rate | Confidence | Likely Cause | Recommendation |
|------|--------|-----------|------------|--------------|----------------|
| [test_name] | [system] | [N]% | confirmed | Timing | Quarantine + fix async |
| [test_name] | [system] | [N]% | confirmed | Float comparison | Fix: use epsilon compare |
| [test_name] | [system] | [N]% | suspected (fewer than 3 runs) | Order dependency | Collect more runs before acting |

### Clean Tests (no flakiness detected)

[N] tests ran across [N] runs with consistent results — no flakiness detected.

### Data Limitations

[Note if fewer than 5 runs were available — fewer runs = less statistical confidence]

7. 更新回归套件 + 可选报告文件

询问:“我可以更新 tests/regression-suite.md 的隔离部分, 添加发现的不稳定测试吗?”

如果同意:使用 Edit 将条目追加到 Quarantined Tests 表格中。 绝不要移除现有的隔离条目——只能添加新条目。

另行询问:“我可以将完整的不稳定性报告写入 production/qa/flakiness-report-[date].md 吗?”

完整报告包含逐个测试的分析、原因详情和 针对引擎的修复代码片段。

写入后:

  • 对于每个隔离的测试:“添加针对引擎的跳过注解, 在 CI 中禁用此测试。根本原因修复后重新启用。”
  • 对于符合修复条件的测试:“[test] 的修复很简单—— 将第 [N] 行的相等比较改为使用 is_equal_approx。”
  • 总结:“应用所有隔离注解后,CI 应该会通过。 请在发布门禁前安排修复这 [N] 个隔离测试。”

协作协议

  • 绝不删除测试文件——隔离意味着添加注解 + 列出测试,而不是移除
  • 统计置信度很重要——运行次数少于 3 次时,将发现标记为 “疑似”而非“已确认”;询问是否有更多运行数据
  • 修复始终是目标——隔离只是临时措施;即使建议隔离,也要指出修复方向
  • 写入前先询问——更新回归套件和报告文件都需要明确批准。写入时:结论:已完成——不稳定性报告已写入。拒绝时:结论:受阻——用户拒绝写入。
  • CI 中的不稳定性是团队问题——清楚列出相关测试和建议采取的措施;不要在团队不知情的情况下悄悄隔离测试

评论

支持 Markdown