用于定位不稳定Python测试原因的工具

Hacker News Top 工具

摘要

pytest-leak-finder 是一个 pytest 插件,它使用二分查找来识别当一起运行时,哪个更早的测试导致后续测试失败。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/08/03 01:29

mgaitan/pytest-leak-finder

来源: https://github.com/mgaitan/pytest-leak-finder

PyPI 版本 (https://pypi.org/project/pytest-leak-finder) Python 版本 (https://pypi.org/project/pytest-leak-finder) CI (https://github.com/mgaitan/pytest-leak-finder/actions/workflows/ci.yml)

你有一个测试,单独执行时通过,但在运行整个测试套件时却失败了。发生了什么?依我看,是某个之前的测试把环境弄脏了。但到底是哪个/哪几个呢?可能前面的测试有一大堆,对吧?

这个插件通过对目标之前的已收集测试进行二分搜索类似于 git bisect)来帮助找出罪魁祸首。

第一次运行时,它会收集这些测试的前半部分,再加上失败的测试(即目标)。如果目标失败,说明我们走对了路,于是继续做新的二分。当目标没有失败时,它会改变下一次二分的“一半”范围。

考虑以下示例:

$ pytest -v demo/test_demo.py 
collected 6 items                                                                                                                                            
tests/test_demo.py::test1 PASSED                                                                             
tests/test_demo.py::test2 PASSED                                                                              
tests/test_demo.py::test3 PASSED                                                                              
tests/test_demo.py::test4 PASSED                                                                             
tests/test_demo.py::test5 FAILED                                                                              
tests/test_demo.py::test6 PASSED 

$ pytest -v --lf demo/test_demo.py 
collected 6 items / 5 deselected / 1 selected                                                                                                                
tests/test_demo.py::test5 PASSED 

你可以使用 pytest-leak-finder 来找出有问题的测试。

第一次运行时,它会把失败的测试设为“目标”,并停止本次会话。

$ pytest -v --leak-finder demo/test_demo.py 
collected 6 items

tests/test_demo.py::test1 PASSED                                                                              
tests/test_demo.py::test2 PASSED                                                                              
tests/test_demo.py::test3 PASSED                                                                              
tests/test_demo.py::test4 PASSED                                                                              
tests/test_demo.py::test5 FAILED

===================================================== Leak finder =====================================================
Target set to: pytest-leak-finder/tests/test_demo.py::test5

Next step: a
Current target is: pytest-leak-finder/tests/test_demo.py::test5
============================================= 1 failed, 4 passed in 0.13s =============================================

第二次执行将运行目标之前已通过测试的前半部分(步骤“a”,由 test1test2 组成)。

如果目标仍然失败,就会继续深入这条路径并再次分割。但在这个示例中,它通过了,所以我们会丢弃这一半,并认为另一半包含了泄漏源。这就是为什么“下一步”会是“ba”。

$ pytest -v --leak-finder demo/test_demo.py
collected 6 items / 3 deselected / 3 selected                                                                                                                
demo/test_demo.py::test1 PASSED                                                                                 [ 33%]
demo/test_demo.py::test2 PASSED                                                                                 [ 66%]
demo/test_demo.py::test5 PASSED                                                                                 [100%]

===================================================== Leak finder =====================================================
We reach the target and nothing failed. Let's change the last half.

Next step: ba
Current target is: pytest-leak-finder/demo/test_demo.py::test5
=========================================== 3 passed, 3 deselected in 0.03s ===========================================

因此,新的步骤将是“B-A”,即 test3

$ pytest -v --leak-finder demo/test_demo.py
collected 6 items / 3 deselected / 3 selected                                                                                                                
tests/test_demo.py::test3 PASSED                                                                              
tests/test_demo.py::test5 FAILED

===================================================== Leak finder =====================================================
We found a leak!

Leak found in: pytest-leak-finder/demo/test_demo.py::test3
Last step was: ba

就是这样,test3 正是我们要找的问题测试!

相似文章

pytest-dev/pytest

GitHub Trending (daily)

pytest 是一个成熟的 Python 测试框架,可以轻松编写简单的测试,同时能够扩展以支持应用程序和库的复杂功能测试。

用 LLM 揪出 Python C 扩展的 bug

Lobsters Hottest

Daniel Diniz 借助 Claude Code 与自研插件,系统性地在 44 个 Python C 扩展项目中挖出 575+ 个 bug,其中 14 个项目已合并修复。

插件案例研究:Pluggy

Eli Bendersky

一篇博客文章,探讨了Pluggy——这是一个最初源自pytest的Python库,用于构建插件系统。内容包括其工作原理以及如何将其与一个玩具级HTML转换工具配合使用。

一个简单的运行时不变量挖掘器

Lobsters Hottest

本文用Python实现了一个Daikon风格的运行时不变量挖掘器,包括插桩、轨迹收集、候选不变量检查以及基于蕴含的抑制,为回归测试提供了一个近似预言。