CCGS 非确定性测试检测指南:用 /test-flakiness 技能定位抖动测试并守护测试套件稳定性 CCGS 非确定性测试检测指南用 /test-flakiness 技能定位抖动测试并守护测试套件稳定性【免费下载链接】Claude-Code-Game-StudiosTurn Claude Code into a full game dev studio — 49 AI agents, 72 workflow skills, and a complete coordination system mirroring real studio hierarchy.项目地址: https://gitcode.com/GitHub_Trending/cl/Claude-Code-Game-StudiosClaude Code Game StudiosCCGS在其 Skill Testing Framework 的质量保障层中定义了/test-flakiness技能用于检测测试套件中的非确定性non-deterministic测试。本文以 test-flakiness.md 测试规范为主体完整展开该技能的分析模式、判定等级、五种典型抖动模式、五个可执行的测试用例并结合仓库中 qa-lead 角色、analysis 类目质量指标以及 test-setup / test-helpers / regression-suite 等相邻技能说明其在真实游戏研发流程中的位置与用法。读完本文你将掌握抖动测试的完整检测协议如何基于测试历史日志计算通过率、如何在无历史时退回源码模式扫描、如何区分 SUSPECT 与 CONFIRMED 判定以及如何把检测结果沉淀为可供 QA Lead 决策的报告。技能定位面向 QA Lead 的只读分析技能/test-flakiness是 CCGS 技能体系中analysis类目下的一个成员同属该类的还有 consistency-check、code-review、security-audit 等。根据规范它的核心职责是通过分析测试历史日志如果可用或扫描测试源代码中常见的抖动模式无种子随机数、实时等待、外部 I/O检测非确定性测试。其行为约束非常明确不触发任何导演门禁Director Gate抖动检测是面向 QA Lead 的顾问型质量技能不调用任何导演代理不主动写入文件技能本身是只读的只有用户明确同意后才可能产出可选报告需先询问 May I write三种判定结论NO FLAKINESS无抖动、SUSPECT TESTS FOUND疑似抖动、CONFIRMED FLAKY确认抖动。这一分析→提示→人工决策的定位与 quality-rubric.md 中 analysis 类目的质量指标完全吻合AN1 — 只读扫描分析阶段只用 Read/Glob/Grep不写不编辑、AN2 — 结构化发现表输出必须包含发现表/清单而非纯散文、AN3 — 禁止自动写任何建议的写入都要以 May I write 把关、AN4 — 分析期不触发导演门禁产生发现供人工评审。这正是理解该技能一切行为的前提。双模式分析机制历史优先源码兜底规范的第一条 Protocol Compliance 明确规定了分析路径的优先级读取测试历史日志可用时不可用时退回源码分析模式一历史日志分析History-based Analysis当production/qa/test-history/目录存在且包含多次运行的日志时技能按以下步骤工作读取production/qa/test-history/下的测试运行日志对每个测试计算其在所有可用运行中的通过率pass rate以95% 通过率为阈值进行 SUSPECT 分类低于阈值的测试按名称标记记录失败模式如错误信息不一致、有时超时有时数值错误并给出通过率分数与百分比给出建议调查该测试的时序依赖或状态依赖。规范特别强调见 Coverage Notes95% 阈值是实现细节测试验证的是间歇性失败会被标记这一行为而不是具体的阈值数值。这意味着实现方可以根据项目实际运行量调整阈值而不破坏协议。模式二源码模式扫描Source-only Analysis当production/qa/test-history/不存在时技能明确提示No test history available — analyzing source code for flakiness patterns only然后扫描所有测试文件中的已知抖动模式详见下一节对命中项标记为FLAKINESS RISK源码模式层面的风险而非历史确认。规范要求必须清晰标注当前使用的分析模式历史模式 vs 纯源码模式因为这会直接影响判定的置信度——源码模式只能得到 SUSPECT永远不能得到 CONFIRMED。五大抖动模式源码扫描的判定依据综合 test-flakiness.md 的测试用例与相邻的 test-evidence-review.md 规范技能源码扫描覆盖以下典型模式前两类直接出现在本技能用例中模式检测特征典型代码GDScript 示例风险等级无种子随机数randf()/randi()等调用之前没有seed()调用var roll randf() # unseeded random — non-deterministicFLAKINESS RISK实时时钟断言用实时时钟做断言基准如OS.get_ticks_msec()assert_lt(OS.get_ticks_msec() - start, 100)FLAKINESS RISK实时等待基于真实时间的等待而非信号/mock如create_timer(1.0)await get_tree().create_timer(1.0).timeoutFAIL违反确定性标准直接外部 I/O测试直连真实 API / 文件系统如 HTTPRequest 直呼线上 URLHTTPRequest.new().request(https://api.example.com/auth)FAIL违反隔离标准环境性失败缺失资源、平台不符导致的失败非测试自身非确定性—由技能区分处理不计入抖动其中无种子随机数是 Case 3 的核心场景loot_drop_test.gd中randf()前没有seed()调用导致每次运行产生的随机序列不同断言assert_gt(roll, 0.5)的结果随运行而波动。技能的修复建议是在随机调用前设置种子seeding或对随机函数进行 mockmocking。需要注意规范在 Coverage Notes 中划出的边界因环境问题缺失资源、平台不符导致的测试失败不属于抖动。技能需要区分环境失败与测试自身非确定性两种情形前者是环境配置问题后者才是本技能的扫描对象。三种判定等级的语义与证据要求规范的判定体系是分层的证据强度不同结论置信度不同判定触发条件证据要求动作NO FLAKINESS所有测试在全部运行中一致通过或源码扫描无命中历史数据或源码扫描不写任何文件SUSPECT TESTS FOUND存在低于通过率阈值的测试如 7/10、70%或源码中发现抖动模式历史日志中的间歇失败或源码模式按名称标记、展示通过率、记录失败模式、建议调查CONFIRMED FLAKY历史日志显示反复失败如 10 次运行失败 6 次仅限历史证据源码模式不足以确认呈现发现可选项提供书面报告需 May I write关键语义区别Case 3 断言明确要求源码模式命中只能给出 SUSPECT TESTS FOUND绝不能升级为 CONFIRMED FLAKY——因为缺乏历史运行数据来确认抖动。CONFIRMED 判定是历史证据的专属权力。五个测试用例技能行为的完整验证矩阵规范通过 5 个带 fixture 的测试用例把上述行为固化为可自动验证的断言。这些用例同时也是理解技能内部执行流程的最佳入口。Case 1快乐路径 — 历史干净无抖动Fixtureproduction/qa/test-history/包含 10 次运行的日志所有测试 10 次全部通过每测试 100% 通过率无失败模式。预期行为技能读取测试历史日志计算每个测试跨 10 次运行的通过率全部通过、无不一致 → 判定NO FLAKINESS不写入任何文件。断言要点历史可用时读取历史按测试计算跨运行通过率全部一致通过时判定无抖动零文件写入。Case 2疑似抖动 — 历史中存在间歇性失败Fixture10 次运行日志中test_combat_damage_applies_crit_multiplier通过 7 次、失败 3 次且失败信息不一致有时超时、有时数值错误。预期行为计算通过率为70%7/10低于 95% 阈值按名称标记为 SUSPECT展示通过率分数与百分比与失败模式判定SUSPECT TESTS FOUND建议调查该测试的时序依赖或状态依赖。断言要点低于阈值的测试按名称标记每个疑似测试展示通过率分数与百分比可检测到时记录失败模式给出调查建议。注意这里的失败信息不一致一会儿 timeout、一会儿 wrong value本身就是非确定性的强信号——若每次失败原因相同反而更像确定性缺陷。Case 3源码模式 — 无种子随机数Fixture无历史日志tests/unit/loot/loot_drop_test.gd包含var roll randf() # unseeded random — non-deterministic assert_gt(roll, 0.5, Loot should drop above 50%)预期行为找不到历史日志退回源码分析检测到randf()调用前无seed()调用标记为 FLAKINESS RISK源码模式非历史确认判定SUSPECT TESTS FOUND模式检测到但无历史确认建议在调用前播种或 mock 随机函数。断言要点无历史时启用源码分析兜底未播种随机数被识别为抖动风险判定严格停留在 SUSPECT无历史可确认修复建议明确指向 seeding 或 mocking。Case 4无历史 — 纯源码分析覆盖常见模式Fixtureproduction/qa/test-history/不存在tests/下 15 个测试文件扫描发现 2 个测试用OS.get_ticks_msec()做时序断言无其他模式命中。预期行为检查历史——未找到明确提示无历史可用仅做源码模式扫描扫描已知模式无种子随机、实时等待、系统时钟使用2 个使用OS.get_ticks_msec()的测试被标记为 FLAKINESS RISK判定SUSPECT TESTS FOUND。断言要点明确声明当前处于纯源码分析模式覆盖三类常见模式扫描随机、时间类断言、外部 I/OOS.get_ticks_msec()用于断言被标记为抖动风险源码模式命中时给出 SUSPECT 判定。这个用例直接验证了技能在从未配置过测试历史的早期项目中也能正常工作。Case 5门禁合规 — 无门禁报告仅作建议Fixture测试历史显示 1 个 CONFIRMED FLAKY 测试10 次运行失败 6 次review-mode.txt内容为full。预期行为分析历史识别 1 个已确认抖动的测试无论 review mode 是什么都不触发任何导演门禁判定CONFIRMED FLAKY呈现发现提供可选的书面报告若用户选择写入May I write toproduction/qa/flakiness-report-[date].md?断言要点任何评审模式下都不调用导演门禁CONFIRMED FLAKY 判定必须基于历史证据仅源码模式不够可选报告写入前必须征得 May I write报告对 qa-lead 仅作建议技能不会自动禁用任何测试。与其他 QA 技能的协同工作流/test-flakiness不是孤立运行的。在 CCGS 的 QA 工作流中它与多个相邻技能构成完整闭环/test-setup搭建测试框架无框架时的前置步骤 → /test-helpers生成确定性工厂函数与 mock 桩 → 测试编写与运行CI 产生测试历史 → /test-flakiness本文技能检测抖动 → /test-evidence-review评审测试命名/确定性/隔离性等质量标准 → /regression-suite将 AC 映射到测试断言产出覆盖报告 → /gate-check触发 QL-TEST-COVERAGE 等导演门禁单独技能关键协同点上游依赖test-setup 按引擎搭建tests/unit/、tests/integration/、tests/performance/、tests/playtest/四层结构Godot 用 GdUnit4、Unity 用 asmdef、Unreal 用 headless runner。若发现production/qa/test-history/从未产生过日志说明 CI 测试运行尚未建立可回溯检查 test-setup 与 CI 配置。确定性共建test-helpers 生成的工厂函数要求使用依赖注入无单例mock 桩则用于隔离外部依赖——这正是从源头消灭抖动随机数、实时时钟、外部 I/O的工程手段与本技能扫描的模式一一对应。兄弟技能test-evidence-review 从另一角度评审测试质量命名规范、Arrange/Act/Assert 结构、确定性、隔离性、无硬编码魔数其 Case 2/3 中把create_timer(1.0)实时等待和直连外部 API 判为 FAIL 级发现与本技能的扫描模式高度重合两技能共享同一套对什么是好测试的定义。覆盖维度补充regression-suite 回答AC 有没有测试覆盖本技能回答测试稳不稳定确定性二者互补且都归属production/qa/目录产出报告。下游交接发现确认的抖动测试后报告供 qa-lead 决策。qa-lead 的 Case 4 展示了相关冲突处理范式当 gameplay-programmer 与 qa-lead 就定时断言是否够确定性产生分歧时qa-lead 承认技术性抖动关切并升级到 lead-programmer 做技术裁决而非单方面覆盖——这与本技能仅报告、不自动禁用测试的建议性质一脉相承。完整质量门禁本技能与 test-evidence-review 均不触发导演门禁而覆盖率的正式把关由/gate-check触发的 QL-TEST-COVERAGE 门禁qa-lead 的另一个 Gate ID负责属于独立技能调用见 test-evidence-review.md 的 Case 5。协议合规清单与验证方法技能自身的合规要求规范结尾的 Protocol Compliance 是对/test-flakiness行为的最终验收清单历史日志可用时读取历史不可用时退回源码分析清晰标注当前使用的分析模式历史 vs 纯源码使用抖动阈值如 95% 通过率进行 SUSPECT 分类CONFIRMED FLAKY 必须基于历史证据SUSPECT 可覆盖纯源码模式不禁用、不修改任何测试文件不触发导演门禁判定严格限定为三选一NO FLAKINESS/SUSPECT TESTS FOUND/CONFIRMED FLAKY。如何用 /skill-test 验证本技能本仓库的测试框架支持用/skill-test对技能进行自动化验证见 skill-test.md静态检查/skill-test static test-flakiness验证 5 项结构断言——frontmatter 必需字段name、description、argument-hint、user-invocable、allowed-tools、≥2 个 phase 标题、包含三个判定关键词、不含强制 May I write 语言只读技能可选报告才需批准、存在下一步交接next-step handoff。规范评估/skill-test spec test-flakiness逐条评估上述 5 个测试用例的断言产生按用例的 PASS/FAIL 表最终判定 PASS全部通过/ PARTIAL部分/ FAIL多数失败。覆盖说明与已知边界规范 Coverage Notes 明示了两点重要边界引用时需注意阈值是实现细节95% 是建议值测试验证的是间歇失败会被标记而非具体阈值数字——实现方可按项目调整。环境失败 ≠ 抖动缺失资源、平台不符导致的失败应被区分对待不被计为非确定性这一区分在测试用例层面未被显式覆盖。依据 CLAUDE.md 的说明所有 spec 描述的是当前行为而非理想行为可能编码了已知缺陷当技能在实践中表现异常时应先修正技能再更新 spec——spec 失败应视为需要调查而非技能必然有错。实践落地建议要在真实游戏项目中把/test-flakiness用起来推荐按如下顺序落地先搭骨架运行/test-setup建立引擎对应的测试目录与 runnerGodot 的godot --headless --script tests/gdunit4_runner.gd等 CI 命令见 test-setup.md确保测试可重复运行并能沉淀历史日志到production/qa/test-history/。从源头防抖编写测试时优先使用/test-helpers生成带依赖注入的工厂函数与 mock 桩避免测试直连外部 API、依赖实时时钟或未播种的随机数。常态化检测定期调用/test-flakiness。早期无历史日志时它会自动进入源码扫描模式仍能抓出未播种随机数、OS.get_ticks_msec()时序断言等隐患积累运行日志后升级为通过率统计识别间歇失败。分级处置SUSPECT 级发现组织排查优先怀疑时序与共享状态依赖CONFIRMED FLAKY 级写入production/qa/flakiness-report-[date].md报告先征得 May I write交由 qa-lead 决定修复优先级与是否纳入发布质量门槛——绝不自动禁用测试。双技能交叉验证对同一批测试配合/test-evidence-review做命名、结构、确定性、隔离性评审用/regression-suite确认 AC 覆盖无缺口三者共同支撑发布前的质量证据链。结语/test-flakiness是 CCGS 质量保障层中确定性维度的守门人。它用最小的介入成本只读扫描、无门禁、无自动写把测试是不是真的稳定从一个模糊的担忧转化为可复现的三级判定无抖动、疑似抖动、确认抖动。其双模式分析设计让它在项目早期无历史数据和成熟期有完整历史都能有效工作而严格的证据分级源码模式永远只能 SUSPECT、CONFIRMED 只认历史保证了结论的严谨性。对于任何用 AI 代理驱动的游戏开发流水线这都是一份值得直接复用的抖动测试检测协议。【免费下载链接】Claude-Code-Game-StudiosTurn Claude Code into a full game dev studio — 49 AI agents, 72 workflow skills, and a complete coordination system mirroring real studio hierarchy.项目地址: https://gitcode.com/GitHub_Trending/cl/Claude-Code-Game-Studios创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考