在 的子類中QFileDialog有一個方法 ,on_dir_entered當QFileDialog的信號directoryEntered觸發時應呼叫該方法,因此:
self.directoryEntered.connect(self.on_dir_entered)
問題是信號需要不可忽略的時間才能生效。最初,我的靈感來自著名的 PyQt5 專家 eyllanesc 的回答。通過單獨的測驗,使用這種技術QTimer.singleShot()可以作業,盡管我從一開始就對它有模糊的懷疑。事實上,事實證明,在我的機器上,我遇到了這種事情的“測驗泄漏”,特別是當有不止一種這樣的測驗方法時:在測驗本身之外顯然發生了奇怪的錯誤:
TEARDOWN ERROR: Exceptions caught in Qt event loop:
...所以我回到 pytest-qt 檔案,發現有各種可用的方法開始wait...似乎可以解決信號或其他事件的問題,這些方法需要花費不可忽略的時間才能產生效果。所以我做了一些嘗試來測驗信號directoryEntered:
def test_directoryEntered_triggers_on_dir_entered(request, qtbot, tmpdir):
project = mock.Mock()
project.main_window = QtWidgets.QWidget()
project.home_dir_path = pathlib.Path(str(tmpdir))
fd = save_project_dialog_class.SaveProjectDialog(project)
with mock.patch.object(fd, 'on_dir_entered') as mock_entered:
fd.directoryEntered.emit('dummy')
qtbot.waitSignal(fd.directoryEntered, timeout=1000)
mock_entered.assert_called_once()
進而
def test_directoryEntered_triggers_on_dir_entered(qtbot, tmpdir):
project = mock.Mock()
project.main_window = QtWidgets.QWidget()
project.home_dir_path = pathlib.Path(str(tmpdir))
fd = SaveProjectDialog(project)
qtbot.waitSignal(fd.directoryEntered, timeout=1000)
with mock.patch.object(fd, 'on_dir_entered') as mock_entered:
fd.directoryEntered.emit('dummy')
mock_entered.assert_called_once()
進而
def test_directoryEntered_triggers_on_dir_entered(qtbot, tmpdir):
project = mock.Mock()
project.main_window = QtWidgets.QWidget()
project.home_dir_path = pathlib.Path(str(tmpdir))
fd = SaveProjectDialog(project)
with mock.patch.object(fd, 'on_dir_entered') as mock_entered:
fd.directoryEntered.emit('dummy')
qtbot.wait(1000)
mock_entered.assert_called_once()
全部失敗:該方法被呼叫 0 次。
我也試過:
def test_directoryEntered_triggers_on_dir_entered(qtbot, tmpdir):
project = mock.Mock()
project.main_window = QtWidgets.QWidget()
project.home_dir_path = pathlib.Path(str(tmpdir))
fd = SaveProjectDialog(project)
with mock.patch.object(fd, 'on_dir_entered') as mock_entered:
fd.directoryEntered.emit('dummy')
def check_called():
mock_entered.assert_called_once()
qtbot.waitUntil(check_called)
...這超時(默認 5000 毫秒)。我已經雙重檢查和三重檢查了connect在這個信號上設定的代碼是否被執行。
之后
通過print在被呼叫的插槽 ( on_dir_entered) 中放置一條陳述句,我現在看到了問題所在:盡管有這with mock.patch...條線,但該方法并沒有被嘲笑!
在我對嘲諷等方面的知識水平較低時,我傾向于假設這是因為使用信號emit()觸發事件的事實:我想不出另一種解釋。
注意這個信號是由 a 中的一兩個事件“自然地”觸發的QFileDialog(例如單擊“轉到父目錄” QToolButton)。也許你必須這樣做......所以我試過這個:
def test_directoryEntered_triggers_on_dir_entered(request, qtbot, tmpdir):
project = mock.Mock()
project.main_window = QtWidgets.QWidget()
project.home_dir_path = pathlib.Path(str(tmpdir))
fd = save_project_dialog_class.SaveProjectDialog(project)
to_parent_button = fd.findChild(QtWidgets.QToolButton, 'toParentButton')
print(f'qtbot {qtbot} type(qtbot) {type(qtbot)}')
with mock.patch.object(SaveProjectDialog, 'on_dir_entered') as mock_entered:
qtbot.mouseClick(to_parent_button, QtCore.Qt.LeftButton)
def check_called():
mock_entered.assert_called_once()
qtbot.waitUntil(check_called, timeout=1000)
暫停。0 次呼叫。我再次能夠確定正在呼叫真正的方法,并且補丁不起作用。
我做錯了什么,有沒有辦法用 pytest-qt 中的東西來測驗這個?
uj5u.com熱心網友回復:
我想我可能已經找到了答案。pytest-qt 的專家可能想發表評論。
我想我發現(這可能很明顯)上述嘗試使用的問題qtbot.waitUntil()是,一旦執行離開背景關系管理器塊,我設定的補丁就不再應用,并且對該方法的呼叫確實是,延遲,這是重點。
因此,整體測驗方法裝飾器補丁是一種方法(或者在設定補丁背景關系管理器后保留縮進......)。我發現以下兩個都通過了,而且都不是誤報(即,如果我注釋掉設定 的應用程式代碼行,它們就會失敗connect):
@mock.patch('SaveProjectDialog.on_dir_entered')
def test_directoryEntered_signal_triggers_on_dir_entered(mock_entered, request, qtbot, tmpdir):
project = mock.Mock()
project.main_window = QtWidgets.QWidget()
project.home_dir_path = pathlib.Path(str(tmpdir))
fd = SaveProjectDialog(project)
fd.directoryEntered.emit('dummy')
def check_called():
mock_entered.assert_called_once()
qtbot.waitUntil(check_called, timeout=1000)
@mock.patch('SaveProjectDialog.on_dir_entered')
def test_on_click_toParentButton_triggers_on_dir_entered(mock_entered, request, qtbot, tmpdir):
project = mock.Mock()
project.main_window = QtWidgets.QWidget()
project.home_dir_path = pathlib.Path(str(tmpdir))
fd = SaveProjectDialog(project)
to_parent_button = fd.findChild(QtWidgets.QToolButton, 'toParentButton')
qtbot.mouseClick(to_parent_button, QtCore.Qt.LeftButton)
def check_called():
mock_entered.assert_called_once()
qtbot.waitUntil(check_called, timeout=1000)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/362573.html
標籤:Python 异步 pytest 信号槽 pytest-qt
上一篇:參考時執行的js異步函式
