LoginSignup
1
2

More than 5 years have passed since last update.

GUIアプリケーションのメニュー選択をpytestでテスト

Posted at

GUIアプリケーションのメニューから、正しいメソッドが呼び出されていることを確認するテストです。pytest-qtのissueに書かれていますが、実際にメニューを選択することは難しいとのことで、メニュー項目に割り当てられているQActionオブジェクトにtriggerイベントを発生させること代用することを勧められています。

前提条件

開発環境

対象とするGUIアプリケーションはPython+Qtで開発されているとします。Qtのライブラリは以下のいずれにも対応するとのことですが、PySide2環境で検証しました。

  • PySide2
  • PySide
  • PyQt5
  • PyQt4

インストールするパッケージ

以下のパッケージが必要です。

pip install pytest pytest-qt pytest-mock

作業手順

サンプルのプログラム

メニューが「メニュー」一つ、それにメニュー項目が「アクション」の一つのみのシンプルなプログラムです。

qiita.py
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QMainWindow
from PySide2.QtWidgets import QAction
from PySide2.QtWidgets import QMenu

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        menu = QMenu('メニュー', self)
        action = QAction('アクション', menu)
        action.setObjectName('action')
        action.triggered.connect(self.action_function)
        menu.addAction(action)
        self.menuBar().addMenu(menu)

    def action_function(self):
        print('アクション')
        return


def main() -> None:
    app = QApplication()
    window = MainWindow()
    window.show()
    app.exec_()

if __name__ == '__main__':
    main()

注意点としては、テストスクリプトからメニュー項目のQActionオブジェクトを検索するために、以下を設定しています。

  • メニュー項目のQActionオブジェクトにオブジェクト名を設定
  • MainWindow(QWindowのサブクラス), QMenu, QActionが親子関係

テストスクリプト

「アクション」項目に正しいメソッド(ここではaction_function)が設定されているかを確認するテストスクリプトです。

test_qiita.py
from PySide2.QtWidgets import QAction

from qiita import MainWindow

def test_qiita(qtbot, mocker):
    window = MainWindow()
    mocker.patch.object(MainWindow, 'action_function')
    window.findChild(QAction, 'action').trigger()
    MainWindow.action_function.assert_called_once_with()

テストスクリプトは以下の動作をします。

  1. 呼び出されるべきaction_functionをモックに置き換えます。
  2. テスト対象のメニュー項目に該当するQActionオブジェクトをfindChildメソッドで検索して、trigger()イベントを発生します。
  3. 置き換えたモックが呼び出された回数を確認します。

テストの実行

以下のコマンドを実行します。

$ pytest test_qiita.py

以下のように出力されます。

============================= test session starts ==============================
platform linux -- Python 3.6.7, pytest-4.1.1, py-1.7.0, pluggy-0.8.1 
cachedir: .pytest_cache
PySide2 5.12.0 -- Qt runtime 5.12.0 -- Qt compiled 5.12.0
rootdir: /home/user1/projects, inifile:
plugins: qt-3.2.2, mock-1.10.0
collected 1 item                                                               

test_qiita.py::test_qiita PASSED                                         [100%]

=========================== 1 passed in 0.19 seconds ===========================
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2