Reputation: 3620
I use PyQt5.6, Python 3.5 and Windows for a hobby project where I have an app with some actions (QAction
) that have shortcuts set (for key combinations Ctrl-N
and Ctrl-B
, for example). I have written unit tests to verify that those actions can be triggered and they do what they should.
However, I am not able to find any working example of how to trigger an action using a shortcut that has been set when writing a unit test with QTest
.
To support the question, this is the minimal application code:
import sys
from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import QMainWindow, QApplication, QAction, QLabel
########################################################################
class Window(QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
action1 = QAction("&Action1", self)
action1.setShortcut("Ctrl+U")
action1.triggered.connect(self.update_label)
self.label = QLabel('Empty', self)
self.setCentralWidget(self.label)
main_menu = self.menuBar()
file_menu = main_menu.addMenu("&File")
file_menu.addAction(action1)
self.show()
def update_label(self):
print("updating label")
self.label.setText('Updated label')
if __name__ == '__main__':
app = QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
The app has one action which can be triggered by Ctrl-U
. The app works as expected. Now I have written a unit test suite:
import unittest
from PyQt5.QtWidgets import QApplication
from PyQt5.Qt import QKeySequence
from PyQt5.Qt import Qt
from myapp import Window
from PyQt5.QtTest import QTest
########################################################################
class Test(unittest.TestCase):
#----------------------------------------------------------------------
def setUp(self):
self.app = QApplication([])
self.ui = Window()
self.menu = self.ui.menuBar()
#----------------------------------------------------------------------
def test_update_label_from_menu(self):
self.assertEqual(self.ui.label.text(), 'Empty')
self.menu.actions()[0].menu().actions()[0].trigger()
self.assertEqual(self.ui.label.text(), 'Updated label')
#----------------------------------------------------------------------
def test_update_label_from_shortcut(self):
self.assertEqual(self.ui.label.text(), 'Empty')
QTest.keyClicks(self.ui, 'U', Qt.ControlModifier)
print(self.ui.label.text())
QTest.keyPress(self.ui, 'U', Qt.ControlModifier)
print(self.ui.label.text())
QTest.keyPress(self.ui, Qt.Key_U, Qt.ControlModifier)
print(self.ui.label.text())
self.assertEqual(self.ui.label.text(), 'Updated label')
return
#----------------------------------------------------------------------
def tearDown(self):
pass
When the test test_update_label_from_menu
is executed, the action is being triggered and I can see that the label text has been updated and the test passes. However, I am not able to send the shortcut properly using QTest
in the test_update_label_from_shortcut
test (I am trying various combinations). The test fails.
How do I do send the event such as pressing Ctrl-N
using QTest
?
UPDATE:
It looks like I am already using the suggested way in this answer (which is calling QTest.keyClicks(self.window, 'n', Qt.ControlModifier)
) and it does not work for me. Not sure if this matters that much, but the answer refers to PySide, yet I am on PyQt.
UPDATE 2: In order to be able to make the test pass, I had to add QTest.qWaitForWindowExposed(self.ui)
line in the setUp
. Then the key presses can be sent using shortcuts.
Upvotes: 2
Views: 859