有沒有人有解釋爲什麼下面的泄漏內存(內存和其他內核對象,如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