介绍不稳定的测试缓解工具
引言
这篇博文介绍了一个新的Gradle插件和构建扫描的改进,旨在缓解您的不稳定测试。
不稳定的测试通过阻塞CI管道和导致不必要的故障调查来扰乱软件开发周期。不健康的团队通过重新运行构建(有时是多次)来推进更改。Martin Fowler对非确定性测试有尖锐的评论,值得一读。
为了从您的组织中消除这个寄生虫,您必须识别、优先处理并修复不稳定的测试。
缓解不稳定的测试 #
有许多巧妙的启发式方法可以帮助识别不稳定的测试。您可以运行一些静态分析来证明测试失败理论上不会导致给定的测试失败。您可以计算从失败到通过的“翻转”次数,并设置一个阈值,超过该阈值的测试被认为是不稳定的。
这些启发式方法通常有效,但它们真的、真的很难做到正确。当您的不稳定测试检测方法本身就不稳定时,就会出现一个大问题——人们不信任系统,他们会选择重试并忍受,直到他们得到想要的结果。
在相同的执行环境中重新运行测试是识别不稳定测试的可靠方法。难怪这么多团队和库都采用了这种简单的策略。它甚至已经直接内置到Maven Surefire和Failsafe中。
这就是为什么我们开发了测试重试Gradle插件,它会重试失败的测试,以缓解测试的不稳定性。
新的测试重试Gradle插件 #
您可以使用此Gradle配置来重试测试,并可选择在遇到不稳定性时使构建失败
plugins {
id 'org.gradle.test-retry' version '1.0.0'
}
test {
retry {
failOnPassedAfterRetry = true
maxFailures = 42
maxRetries = 1
}
}
plugins {
id("org.gradle.test-retry") version "1.0.0"
}
tasks.test {
retry {
failOnPassedAfterRetry.set(true)
maxFailures.set(42)
maxRetries.set(1)
}
}
这个插件有4个特别出色的方面
- 无需更改测试源代码。这允许
主动检测 新的不稳定测试! - 您可以使用
failOnPassedAfterRetry
控制在遇到不稳定性时构建是失败还是通过。这意味着您可以采用此插件来检测不稳定测试而无需使其静音。 - 您可以使用
maxFailures
阻止在一定数量的测试失败后在测试运行中重试。如果您的构建遇到许多失败,很可能是存在一个主要问题导致许多测试失败,重试是浪费资源。 - 在可能的情况下,测试会在方法级别或更精细的级别重试——无需重新运行整个测试类!
Gradle测试重试插件支持的环境 #
测试重试插件开箱即用地支持Gradle 5.0及更高版本,支持以下测试框架
- JUnit4
- JUnit Platform (JUnit 5)
- Spock
- TestNG
在某些情况下,通过上游测试或下游测试(例如,当使用@Test(dependsOn = {})
时)必须由插件重新执行,以确保当不稳定测试依赖于其所依赖的测试的状态时的正确性。
有关支持的框架和重试机制的更多信息,请参阅测试重试Gradle插件文档。
如何报告不稳定的测试 #
我们选择报告不稳定测试的所有离散执行,以最大程度地兼容现有测试报告和IDE。因此,不稳定测试报告可能如下所示
我们正在努力使不稳定性在您日常使用的更多工具中成为一流的测试结果,以澄清报告。文档中提供了关于如何在日志、测试报告和流行IDE中报告不稳定测试的更多详细信息。
好消息是,构建扫描已经以清晰准确的方式报告了不稳定测试!
构建扫描对不稳定测试的支持 #
当测试在同一次构建中多次执行,且结果既有PASSED也有FAILED(顺序不限)时,Gradle和Maven构建扫描现在将其报告为不稳定测试。这使得构建扫描可以使用内置的重试机制来报告不稳定测试,例如Maven的重新运行失败测试选项(如-Dsurefire.rerunFailingTestsCount=2
)或您的自定义重试机制。
识别并使不稳定测试静音只是治标不治本。很可能存在一些真正的并发或性能问题导致您的客户遭受痛苦——您必须分析不稳定测试的执行情况才能修复它们。您可以在我的博客文章中阅读更多关于分析Maven和Gradle构建中的不稳定测试的信息。
结论 #
我们希望新的测试重试Gradle插件和新的不稳定测试分析功能能帮助您根除不稳定测试。
请在Twitter上告诉我们您的想法。