不稳定的测试¶
“不稳定”测试是指表现出间歇性或偶发性失败的测试,它似乎具有不确定的行为。有时它通过,有时它失败,而且原因不明。本页讨论了可以提供帮助的 pytest 功能以及识别、修复或缓解它们的其它一般策略。
为什么不稳定的测试是一个问题¶
当使用持续集成 (CI) 服务器时,不稳定的测试尤其麻烦,因为在合并新的代码更改之前,所有测试都必须通过。如果测试结果不是一个可靠的信号——测试失败意味着代码更改破坏了测试——开发人员可能会对测试结果失去信任,从而导致忽视真正的失败。这也是浪费时间的一个来源,因为开发人员必须重新运行测试套件并调查虚假失败。
潜在的根本原因¶
系统状态¶
从广义上讲,不稳定的测试表明测试依赖于未得到适当控制的某些系统状态——测试环境未得到充分隔离。由于高级测试依赖于更多状态,因此它们更有可能不稳定。
当测试套件并行运行(例如使用 pytest-xdist)时,有时会出现不稳定的测试。这可能表明测试依赖于测试顺序。
也许另一个测试未能自行清理,并留下了导致不稳定测试失败的数据。
不稳定的测试依赖于前一个测试的数据,而前一个测试未能自行清理,并且在并行运行中,前一个测试并不总是存在
修改全局状态的测试通常无法并行运行。
过于严格的断言¶
过于严格的断言会导致浮点比较问题以及时序问题。 pytest.approx()
在这里很有用。
Pytest 功能¶
Xfail strict¶
pytest.mark.xfail 与 strict=False
可用于标记测试,以便其失败不会导致整个构建中断。这可以被视为手动隔离,并且永久使用相当危险。
PYTEST_CURRENT_TEST¶
PYTEST_CURRENT_TEST
可能有助于找出“哪个测试卡住了”。有关更多详细信息,请参见 PYTEST_CURRENT_TEST 环境变量。
插件¶
重新运行任何失败的测试可以通过给它们更多通过的机会来减轻不稳定测试的负面影响,以便整体构建不会失败。多个 pytest 插件支持此功能
pytest-replay: 此插件有助于在 CI 运行期间本地重现崩溃或不稳定的测试。
故意随机化测试的插件可以帮助揭示存在状态问题的测试
其他一般策略¶
拆分测试套件¶
将单个测试套件拆分为两个(例如单元测试与集成测试)很常见,并且仅将单元测试套件用作 CI 门禁。这也有助于保持构建时间可控,因为高级别测试往往较慢。但是,这意味着破坏构建的代码有可能被合并,因此需要格外注意监控集成测试结果。
失败时录制视频/截图¶
对于 UI 测试,这些对于理解测试失败时的 UI 状态非常重要。pytest-splinter 可与 pytest-bdd 等插件配合使用,并且可以在测试失败时保存截图,这有助于找出原因。
删除或重写测试¶
如果其他测试涵盖了该功能,则可以删除该测试。如果没有,则可以将其重写为更低级别,这将消除不稳定性或使其来源更加明显。
隔离¶
Mark Lapierre 在 2018 年的一篇文章中讨论了隔离测试的优缺点。
在失败时重新运行的 CI 工具¶
Azure Pipelines(Azure 云 CI/CD 工具,以前称为 Visual Studio Team Services 或 VSTS)具有识别不稳定测试并重新运行失败测试的功能。
研究¶
这是一个有限的列表,请提交问题或拉取请求以对其进行扩展!
Gao, Zebao, Yalan Liang, Myra B. Cohen, Atif M. Memon, and Zhen Wang. “Making system user interactive tests repeatable: When and what should we control?.” In Software Engineering (ICSE), 2015 IEEE/ACM 37th IEEE International Conference on, vol. 1, pp. 55-65. IEEE, 2015. PDF
Palomba, Fabio, and Andy Zaidman. “Does refactoring of test smells induce fixing flaky tests?.” In Software Maintenance and Evolution (ICSME), 2017 IEEE International Conference on, pp. 1-12. IEEE, 2017. Google Drive 中的 PDF
Bell, Jonathan, Owolabi Legunsen, Michael Hilton, Lamyaa Eloussi, Tifany Yung, and Darko Marinov. “DeFlaker: Automatically detecting flaky tests.” In Proceedings of the 2018 International Conference on Software Engineering. 2018. PDF
Dutta, Saikat and Shi, August and Choudhary, Rutvik and Zhang, Zhekun and Jain, Aryaman and Misailovic, Sasa. “Detecting flaky tests in probabilistic and machine learning applications.” In Proceedings of the 29th ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA), pp. 211-224. ACM, 2020. PDF
资源¶
消除测试中的非确定性,Martin Fowler,2011 年
Go 团队不再出现不稳定测试,Pavan Sudarshan,2012 年
构建哭泣破损:建立对持续集成测试的信任,Angie Jones 在 SeleniumConf Austin 2017 上的演讲(视频)
测试和代码播客:不稳定测试以及如何处理它们,Brian Okken 和 Anthony Shaw,2018 年
Microsoft
微软如何通过测试 VSTS 来实现持续交付,作者:Brian Harry MS,2017 年
消除不稳定的测试,作者:Munil Shah,博客和演讲(视频),2017 年
Google
Google 中的不稳定测试以及我们如何缓解它们,作者:John Micco,2016 年
Google 的不稳定测试来自何处?,作者:Jeff Listfield,2017 年