私はPyQt5 MainWindow GUIの機能テストを書いています。現在、正しいウィジェットがグリッドレイアウトの正しい座標にあるかどうかを確認しています。私はobjectNameでウィジェットを見つける方法を決め、GUIの(グリッド)レイアウトでウィジェットに "掘り下げる"ために必要なモジュールの階層を見つけましたが、私はこれを難しい方法でやらなければならないと感じています。私はPyQt4/5のドキュメントを読んで、それに関する同様の質問を探していましたが、私の仕事を簡略化するツールは明らかにしていませんでした。ウィジェットとそのレイアウトの場所を名前で見つけるよりも簡潔な方法ですか?
理想的には、私は、次の擬似コードと同様のコマンドを希望:
Bob_widget = widget['Bob'] # lookup widget by objectName
assert Bob_widget.layout.coordinates == (0, 0)
擬似コードの最初の行の機能は、次にfindChildメソッドに各ウィジェットの名前とタイプを渡すによって行うことができます辞書を作っていますが、それに相当するものがあるのだろうかと思います。
擬似コードの2行目は痛みが増します。ウィジェットを見つけるためにGUIをどのようにトンネルするかについて、いくつかの調査が行われました。以下私のGUIのコードのために:
import sys
from collections import namedtuple
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QGridLayout,
QLabel, QDoubleSpinBox)
gui_userinput = namedtuple('gui_userinput', ['key', 'string', 'value', 'range'])
variable_a = gui_userinput(key='variable_a', string='Variable A', value=165.00,
range=(0.00, 10000.00))
variable_b = gui_userinput(key='variable_b', string='Variable B', value=135.00,
range=(0.00, 10000.00))
gui_userinput_order = (variable_a, variable_b)
class Gui(QMainWindow):
def __init__(self, parent=None):
super(Gui, self).__init__(parent)
self.setObjectName('toplevel')
self.setupUi()
def setupUi(self):
centralWidget = QWidget()
centralWidget.setObjectName('centralwidget')
self.setCentralWidget(centralWidget)
centralLayout = QGridLayout()
self.setObjectName('centrallayout')
for i, widget in enumerate(gui_userinput_order):
wlabel = QLabel(widget.string)
wlabel.setObjectName(widget.key + '_label')
wbox = QDoubleSpinBox()
wbox.setObjectName(widget.key)
wbox.setRange(*widget.range)
wbox.setValue(widget.value)
centralLayout.addWidget(wlabel, 0, i)
centralLayout.addWidget(wbox, 1, i)
centralWidget.setLayout(centralLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
ui = Gui()
ui.show()
sys.exit(app.exec_())
メインウィンドウからウィジェットをフェッチするようなステートメントを使用する必要があります。
widget_0_0 = self.ui.centralWidget().layout()\
.itemAtPosition(0, 0).widget()
「GUIウィジェット容器を有する(グリッド)レイアウトを有する中央のウィジェットを有します私が望むウィジェットを保持するグリッド座標(0、0)で。
import sys
from PyQt5.QtWidgets import QApplication, QDoubleSpinBox, QLabel
import mini_ui
app = QApplication(sys.argv)
class TestMainGUi:
def setup(self):
self.ui = mini_ui.Gui()
def test_all_widgets_exist(self):
"""The user finds the expected labels and doublespinboxes."""
for widget in mini_ui.gui_userinput_order:
found_box = self.ui.findChild(QDoubleSpinBox, widget.key)
assert found_box.value() == widget.value
found_label = self.ui.findChild(QLabel, widget.key + '_label')
assert found_label.text() == widget.string
def test_label_0_0(self):
"""The user sees a label for 'Variable A' in the top left corner."""
label_a = self.ui.findChild(QLabel, 'variable_a_label')
print('Found', label_a, 'named', label_a.objectName(), 'in GUI.')
widget_0_0 = self.ui.centralWidget().layout()\
.itemAtPosition(0, 0).widget()
print('Found widget type', type(widget_0_0), 'at grid 0, 0')
print('It is named: ', widget_0_0.objectName())
assert widget_0_0.text() == 'Variable A'
assert widget_0_0 is label_a
def test_alternate_widget_acces(self):
"""Just hacking away trying to find a more terse widget reference"""
label_a = self.ui.findChild(QLabel, 'variable_a_label')
assert 1 == 1
def teardown(self):
pass
および反復ウィジェット座標グリッドにコンポーネントウィジェットに一致するように第二の試験を変更し、それは間違っている感じ:
だから、以下最小例のオフリフテストをコードすることができます。 GUIが変更されて階層が変更された場合、テストは機能しません。テストコードは、GUIの細かい構造を認識している必要があります。
GUIレイアウトの内容をテストするための、より簡潔で堅牢な方法がありますか?私が紛失しているビルトインツールはありますか?
ありがとうございました。