【开源自荐】FlakeGate:别再把 flaky test“重跑到绿”了

zemu宸 2026-07-17 22:28 1

FlakeGate:别再把 flaky test“重跑到绿”了

​ 本帖使用社区开源推广,符合推广要求。我申明并遵循社区要求的以下内容:



  • 我的帖子已经打上 开源推广 标签:

  • 我的开源项目完整开源,无未开源部分:

  • 我的开源项目已链接认可 LINUX DO 社区:

  • 我帖子内的项目介绍,AI生成、润色内容部分已截图发出:

  • 以上选择我承诺是永久有效的,接受社区和佬友监督:


以下为项目介绍正文内容,AI生成、润色内容已使用截图方式发出


最近两三周一直在针对开发方面的问题进行优化,是否还能做一些有意义的开源项目也是挺值得思考的,发现很多地方叶被大厂拿下了,然后在某天项目合作的业务处理上,发现很有意思的一点,我们知道agent时代已经到来了,很快agent集群的落地和agent任务的落地那么它的工程性质回更强,现在遇到一个很场景的问题就是在CI有时候反馈给你出问题,失败的不是刚修改的业务逻辑,而是一个偶尔超时的集成测试。团队已经见过它很多次,所以没有人先分析代码差异,也没有人认真读失败栈。最自然的反应是:“先重跑一下。”第二次运行变绿,合并继续。看起来问题已经解决,但实际上团队失去了一样更重要的东西:对红色构建的信任。

总的问题而言:一旦“重跑到绿”成为默认动作,CI 的失败就不再能清楚回答一个最基本的问题:代码到底坏没坏?开发者会逐渐忽略红灯,发布负责人会依赖经验判断,coding agent 看到的也只是一段没有历史背景的错误信息。Flaky test 的成本不只是多跑几分钟机器。它会污染整个工程系统的决策信号。

接下来我会先针对商用角度去回答这个问题


Retry 为什么不是治理策略


Retry 能降低一次偶发失败阻断流水线的概率,但它没有回答三个问题:


1. 这个测试是否真的已经有 flaky 证据?


2. 如果暂时放行,谁负责修、什么时候到期?


3. 同一份报告里如果出现一个新的真实回归,怎样保证它不会被一起放过去?


简单的 retry 或 blanket quarantine 很容易把“降低噪音”变成“降低警觉”。最危险的结果不是 CI 经常变红,而是团队学会了忽略红色。


因此,一个完整方案至少需要三种能力:检测、隔离和治理。只有检测列表,没有最终 gate,团队仍然要人工猜测;只有 quarantine,没有 owner 和 expiry,临时例外最终会变成永久债务。


FlakeGate 的边界:已知 flaky 可以放行,未知回归必须保持红灯


FlakeGate 是一个本地优先的 flaky-test CI gate。它把每次 CI 产生的标准 JUnit XML 写入本地 SQLite 历史,并从中寻找同一代码上的结果矛盾。


最强的两类证据是:


同一次运行中,一个逻辑测试既通过又失败;


同一个 commit SHA 的不同运行中,同一测试既通过又失败。


五步闭环


这里我就简单描述了!希望佬们有问题开源直接问

FlakeGate 的完整路径不是“检测以后自动跳过”,而是通过:


1. Ingest:每次 CI 结束后读取 JUnit XML;


2. Detect:从 SQLite 历史中寻找同代码矛盾和反复振荡;


3. Suggest:为有证据的 finding 生成待审核的隔离条目;


4. Govern:把 reason、owner、since、expires 写进版本控制;


5. Gate:根据当前报告和有效策略决定最终退出码。


代码没有变化而结果相反,这比“某个测试失败了一次”提供了更明确的 flaky 证据。对于长期在不同 commit 之间反复翻转的测试,FlakeGate 还会计算普通 flip rate 和近期权重更高的 EWMA flip rate。


同时,它保护一个关键性质:一次真实 regression 从绿变红并持续为红,只发生了一次状态翻转,不应该因此被高分识别为 flaky。




有效隔离中的 flaky test 仍然执行、仍然记录、仍然出现在报告里,只是不再阻断合并。未知失败继续阻断。隔离到期后的失败也重新阻断。


Quarantine-as-code


FlakeGate 不把 quarantine 状态藏在一个独立 dashboard 中,而是使用项目仓库里的 `.flakegate.yml`:


这意味着 quarantine 不是测试的坟场,而是一条有负责人、有时钟、有退出条件的修复队列。


配置会拒绝未知字段、错误日期、重复 test ID 和缺失治理字段。条目在 `expires` 当天仍然有效,从第二天开始重新进入阻断路径。


这样做的好处是:隔离通过现有 pull request 流程审核,责任和期限在代码历史中可追踪,不需要再维护一套孤立权限和状态系统。


为什么是 JUnit XML + SQLite + 单二进制


FlakeGate 有意保持一个很窄的集成面。


JUnit XML


pytest、Jest、Maven Surefire、Gradle、gotestsum、RSpec 等大量框架都可以输出 JUnit。与其为每个框架写插件,不如统一读取测试已经产生的报告。


SQLite


历史不需要另一个托管服务。一个 SQLite 文件可以通过 CI 自己的 cache 或 artifact 机制在运行之间传递。测试数据仍留在用户自己的基础设施内。


纯 Go 二进制


FlakeGate 使用 pure-Go SQLite 驱动,不需要 CGO。Linux、macOS 和 Windows 可以使用同一个集成模型。


核心工作流不要求网络。只有可选 BYOK 根因分类和显式启用的 GitHub issue escalation 会访问外部接口。


同一个判断同时提供给人、CI 和 coding agent


FlakeGate 的数据型命令支持稳定 JSON,gate 可以写 GitHub Markdown summary,本地 stdio MCP 则提供 test status、detect、gate 和 quarantine 查询。


这解决了 agentic development 中一个很现实的问题:coding agent 通常只能看到当前失败,却不知道它是否曾经在同一 commit 上通过,也不知道团队是否已经为它建立了有效隔离。


通过本地 MCP,agent 获得的不是一个模糊的“可能 flaky”,而是和 CI 使用同一份历史、同一份配置与同一套边界得出的判断。


部分实验结果因为还没有佬使用过然后这个也在开发阶段我们只能用已经用的数据做了测试


测试结果如下


FlakeGate 的 benchmark 将不同问题拆开验证,因为没有一个数据集能同时证明检测、产业影响、外部覆盖和 gate 安全性。


当前仓库中可复现的主要结果包括:


- FlakeFlagger ICSE 2021:26,765 个带标签测试,其中 828 个 flaky、25,937 个 stable;


- 原始归档回放:47,430 份 Surefire XML、869,550 次测试执行;


- IDoFT 固定快照:10,687 个有效唯一记录、916 个项目和 14 个观察类别;


- 17 个严格定义的固定 revision false-red 运行,对 retry、active quarantine、unknown regression 和 expiry 分别执行 17/17 控制;


- 100,000 次执行的本机 microbenchmark:当前流式聚合测得 13.3 ms、3.83 MB/op 和 10,036 allocs/op。


最后欢迎各位佬能持续提供意见和支持,这个项目算是我除了商业方面看到的算是第一个开源,很多地方都是自己想想,也感谢各位佬的star和关注

GitHub:GitHub - xiao-zi-chen/FlakeGate · GitHub

项目网站:FlakeGate — Make red mean broken again

最新回复 (1)
  • susiddhi 07-17 23:13
    1

    没有看懂,需要再仔细看看。看怎么才能用上

* 帖子来源Linux.do
返回