Как отправить сочетание клавиш для пункта меню с помощью QTest?
В модульном тесте я пытаюсь отправить комбинацию клавиш Command+N (в Mac OS), которая соответствует пункту меню в моем приложении. Я использую модуль PySide.QtTest.
В приведенном ниже коде я использую QTest.keyClicks
, который не производит то, что я ожидаю. Действие, соответствующее ярлыку, не вызывается.
class AppTestCase(TestCase):
def setUp(self):
qApp = QApplication.instance()
if qApp is None:
self.app = QApplication([])
else:
self.app = qApp
class IdfEditorTestCase(th.AppTestCase):
def setUp(self):
super(IdfEditorTestCase, self).setUp()
self.window = IdfEditorWindow()
def test_input_object_in_new_file(self):
if os.path.exists("current_running_test.idf"):
os.remove("current_running_test.idf")
self.window.selectClass("ScheduleTypeLimits")
QTest.keyClicks(self.window, "n", Qt.ControlModifier)
self.window.saveFileAs("current_running_test.idf")
self.assertIdfFileContentEquals("current_running_test.idf", "ScheduleTypeLimits,,,,,;\n")
Некоторые вопросы:
- Должен ли я отправить это в само окно? Или в менубар? Ни один, кажется, не работает...
- Это правильный способ отправки сочетания клавиш?
1 ответ
Для "обычных" тестов нажатия клавиш (например, ввод текста в редактировании строки) нет необходимости показывать окно. Это соответствует тому, что вы ожидаете, если отправите ключевые события в скрытый виджет во время обычного запуска приложения.
Но для тестирования ярлыков должно быть показано целевое окно, которое снова соответствует ожидаемому. Сочетание клавиш не должно активировать команды во время нормального запуска, если целевое окно не видно.
Таким образом, ваш установочный код должен включать что-то вроде этого:
self.window.show()
QTest.qWaitForWindowShown(self.window)
Вызов qWaitForWindowShown необходим в системах, где окна отображаются асинхронно (для Qt5 используйте qWaitForWindowExposed).
РЕДАКТИРОВАТЬ:
Вот тестовый скрипт, который работает для меня:
import unittest
from PySide.QtCore import Qt
from PySide.QtGui import QApplication, QMainWindow, QLineEdit
from PySide.QtTest import QTest
class Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
menu = self.menuBar().addMenu('File')
menu.addAction('Test', self.handleTest, 'Ctrl+N')
self.edit = QLineEdit(self)
self.setCentralWidget(self.edit)
def handleTest(self):
self.edit.setText('test')
class AppTestCase(unittest.TestCase):
def setUp(self):
qApp = QApplication.instance()
if qApp is None:
self.app = QApplication([])
else:
self.app = qApp
class WindowTestCase(AppTestCase):
def setUp(self):
super(WindowTestCase, self).setUp()
self.window = Window()
self.window.show()
QTest.qWaitForWindowShown(self.window)
def test_input_object_in_new_file(self):
text = 'test'
self.assertNotEqual(text, self.window.edit.text())
QTest.keyClicks(self.window, 'n', Qt.ControlModifier)
self.assertEqual(text, self.window.edit.text())
def test_enter_text(self):
text = 'foobar'
self.assertNotEqual(text, self.window.edit.text())
QTest.keyClicks(self.window.edit, text)
self.assertEqual(text, self.window.edit.text())
if __name__ == "__main__":
unittest.main()
ОБНОВЛЕНИЕ:
Вот версия PyQt5 вышеуказанного скрипта:
import unittest
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QLineEdit
from PyQt5.QtTest import QTest
class Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
menu = self.menuBar().addMenu('File')
menu.addAction('Test', self.handleTest, 'Ctrl+N')
self.edit = QLineEdit(self)
self.setCentralWidget(self.edit)
def handleTest(self):
self.edit.setText('test')
class AppTestCase(unittest.TestCase):
def setUp(self):
qApp = QApplication.instance()
if qApp is None:
self.app = QApplication([''])
else:
self.app = qApp
class WindowTestCase(AppTestCase):
def setUp(self):
super(WindowTestCase, self).setUp()
self.window = Window()
self.window.show()
QTest.qWaitForWindowExposed(self.window)
def test_input_object_in_new_file(self):
text = 'test'
self.assertNotEqual(text, self.window.edit.text())
QTest.keyClicks(self.window, 'n', Qt.ControlModifier)
self.assertEqual(text, self.window.edit.text())
def test_enter_text(self):
text = 'foobar'
self.assertNotEqual(text, self.window.edit.text())
QTest.keyClicks(self.window.edit, text)
self.assertEqual(text, self.window.edit.text())
if __name__ == "__main__":
unittest.main()