有没有人有解释为什么下面的泄漏内存(内存和其他内核对象,如GDI和用户句柄在每次迭代中都保持增加,并且在测试退出之前永不退缩):用Pytest的pyqt测试内存泄漏
import pytest
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication, QGraphicsScene, QGraphicsView
class TestCase:
@pytest.mark.parametrize('dummy', range(1000))
def test_empty(self, dummy):
# self.view = None # does NOT fix the leak if uncommented!
self.app = QApplication.instance()
if self.app is None:
self.app = QApplication([])
self.view = QGraphicsView()
self.view.setFixedSize(600, 400)
self.view.setScene(QGraphicsScene())
self.view.show()
QTimer.singleShot(100, self.app.exit)
self.app.exec()
# self.view = None # FIXES the leak if uncommented!
有如有下列条件变为True没有泄漏:
- 如果我无 - IFY视图之前测试方法返回(取消注释的最后一行)
- 如果我使视图本地到 函数而不是自己的成员(并不奇怪给定修复#1)
- 如果我删除装饰器而 而不是在函数顶部有一个“while True”(so测试 本身运行一次,但窗户被重新一遍又一遍)
有趣的是,泄漏不会消失,如果我做任何如下修改:
- 我视图设置为无在函数的开始处而不是在结尾处(注释掉)轧制的测试方法)
- 不用参数化测试方法,我创建了许多测试方法(100,很容易用一个生成测试模块的小python脚本完成),或许多测试类,许多测试模块(这就是我注意到的问题是,我们有一个巨大的测试套件,每个测试套件包含100个测试模块,每个测试模块包含多个类,每个类都有很多测试方法 - 测试套件中的内存泄漏直到最近测试的数量变得足够大以至于操作系统现在pytest在pytest完成运行所有测试之前用完了)。
- 我更换单次呼叫app.exit()由app.closeAllWindows()(我想这可能是这个问题在这个MCVE)
在我们的应用程序的实际测试需要一些在setup_method()中创建对象,因此我们无法避免将PyQt对象分配给测试实例的数据成员。因此,我们现在唯一可行的解决方案是将每种测试方法编辑为由这些方法创建的None-ify PyQt对象,但这很容易出错,更不用说费力(尽管比现状好)。我希望有更好的方法。
视图不拍摄的场景的所有权,所以你应该保持一个参考吧。 – ekhumoro
@ekhumoro是的,实际的代码是这样做的。事实上,你可以用setScene()删除这行,你仍然会有泄漏。 – Schollii
参见https://github.com/pytest-dev/pytest/issues/1649 – dbn