捕获主分支上的不稳定测试
摘要
文章讨论了软件开发中不稳定测试(flaky tests)的问题,并提出一个简单的机械习惯:在使用合并队列时,继续在主分支上运行完整测试套件,并维护一个可见的近期主分支失败列表,以帮助识别和消除不稳定测试。
<header>
<h1>捕获主分支上的不稳定测试</h1>
<time class="meta" datetime="2026-05-14">2026年5月14日</time>
</header>
<p>今天介绍一个小的<a href="https://matklad.github.io/2025/12/06/mechanical-habits.html"><em>机械习惯</em></a>:</p>
<figure class="blockquote">
<blockquote><p>当使用“not rocket science”规则/合并队列时,继续冗余地在主分支上运行完整测试套件。维护一个易于访问的近期主分支失败列表——这些就是需要消除的不稳定测试。</p>
</blockquote>
</figure>
<p>例如,请查看<a href="https://devhub.tigerbeetle.com" class="display url">https://devhub.tigerbeetle.com</a>上的“Flakes”链接。</p>
<figure>
<img alt="" src="https://github.com/user-attachments/assets/09dffa9e-cdae-48e2-a4ed-80278da53bb2" width="2310" height="1746">
</figure>
<p>不稳定测试是指那些偶尔失败、每千次运行中失败一次的测试。这可能是由于真正的缺陷(关于调度的假设在大多数情况下成立),也可能是由于底层基础设施的不稳定(例如,无法从GitHub下载发布版本,或无法在Windows上删除文件夹)。无论哪种情况,不稳定测试都会极大地拖累生产力——随着测试套件规模和复杂性的增长,越来越多的CI运行会无故失败,即使每个单独测试几乎总是通过。</p>
<p>处理不稳定测试颇具挑战:如果你正忙于合并一个PR,而CI因明显的不稳定测试失败,那么仅仅重新运行测试套件的诱惑巨大,尤其是在对基础设施稳定性有一定不满的背景下。</p>
<p>如果你有意进行一些不稳定测试消除工作,那么你的PR绿色通过反而会让你懊恼!而基于他人的PR工作时,首先需要将不稳定测试与真正的失败区分开来。</p>
<p>这就是合并队列的强大之处:如果保证主分支上的每个提交都通过测试,那么主分支上的每个失败都定义上就是不稳定的。将所有此类失败集中到一个列表中,可以压缩时间,优先处理影响最大的不稳定源,并揭示失败之间的相关性。</p>
查看缓存全文
缓存时间: 2026/05/16 03:32
# 在主分支上捕捉不稳定测试
来源:https://matklad.github.io/2026/05/14/catch-flakes-on-main.html
2026年5月14日
今天分享一个小型*机械习惯*(https://matklad.github.io/2025/12/06/mechanical-habits.html):
> 当使用“非火箭科学”规则/合并队列时,继续在主分支上冗余运行完整的测试套件。维护一个近期主分支失败的可访问列表——这些就是要根除的不稳定测试。
示例见 https://devhub.tigerbeetle.com/ 上的“不稳定测试”(Flakes)链接。
不稳定测试是指偶尔会失败的测试,可能每千次运行中出现一次。这可能是由于真正的缺陷(对调度的假设在*大部分*情况下成立),也可能是底层基础设施的不稳定(例如,无法从 GitHub 下载某个版本,或在 Windows 上删除文件夹)。无论哪种情况,不稳定测试都会严重拖累生产力——随着测试套件的规模和复杂性增长,即使单个测试几乎总能通过,越来越多的 CI 运行也会出现随机失败。
处理不稳定测试颇具挑战性——如果你正努力合并一个 PR,而 CI 因明显的不稳定测试而失败,重跑测试套件的诱惑是巨大的,尤其是当你对基础设施的稳定性已有一定不满时。
如果你有心思去消除不稳定测试,那么你的 PR 反而会故意变绿来气你!而审查别人的 PR 则首先需要区分不稳定测试和真正的失败。
这就是合并队列的强大之处:如果能保证主分支上的每次提交都通过测试,那么主分支上的每次失败,从定义上来说,就是一次不稳定测试。将所有这类失败汇总到一个列表中,可以压缩时间,优先处理影响最大的不稳定来源,并揭示失败之间的关联性。
相似文章
用合并队列取代你的CI
本文认为传统CI对AI代理无效,并提出用合并队列取而代之:在合并前运行所有测试,让代理能在破坏构建之前修复问题。
@ericzakariasson:以下是你可以在Cursor中运行的3个循环 1. Flaky-test exterminator /loop 运行测试套件20次,收集每一次间歇性…
描述了Cursor中的一个循环命令,用于自动修复不稳定的测试:多次运行测试套件,收集间歇性失败,并修复或隔离它们,直到连续5次全绿运行。
@kettanaito:越来越多的人向我询问测试资源,所以我把写过的所有内容汇总在一篇文章里。收藏、…
作者将一系列关于软件测试基础的文章进行了汇总,涵盖了测试的目的、断言、代码覆盖率以及处理不稳定性测试等内容。
@PrajwalTomar_: Claude Code 默认发布有缺陷的代码。这个四循环设置能在每个错误完成之前捕获它。→ A Stop h…
PrajwalTomar 分享了一个适用于 Claude Code 的四循环设置,该设置强制在每次变更时执行测试套件,防止在测试失败时标记工作完成,使用单独的模型来确认完成,并将重复错误写入规则文件。
@cline: 这是开始“循环工程”的一种实用方法(一种花哨的说法,指的是除了人类提示智能体以外的其他方式……)
一种实用的“循环工程”方法:使用 Git 钩子脚本在提交前自动检查代码中泄露的密钥和严重漏洞。