Я расследую QTest за Тестирование GUI. Похоже, что в QTest нет механизма асинхронного тестирования сигнал Перезвоните. Я неправильно понимаю, как использовать QTest, или неправильно понимаю предполагаемую функциональность, предоставляемую QTest?
Например, я пытаюсь проверить сигнал, который запускает модальный QMessageBox всплывающее окно в ответ на нажатие QPushButton. Я хочу проверить события и состояние между нажатием кнопки и нажатием «OK» в QMessageBox. Я пытался использовать QSignalSpy.wait()
, QTestEventList.simulate()
, QTest::mouseClick()
, QTest::mouseEvent()
, а также QTRY_VERIFY()
, все из которых при вызове из тестового кода не возвращаются до тех пор, пока не будет нажата кнопка «ОК» во всплывающем окне QMessageBox. Поэтому, чтобы протестировать что-либо до того, как все обработчики событий вернутся, мне нужно будет сделать что-то вроде установки фильтра событий на тестируемый объект и написать свой собственный код асинхронного тестирования.
Это все тот же код, который мы должны были бы написать, если бы не использовали тестовую библиотеку, и мы можем сделать все это без использования QTest. Например, мы можем вручную получить ручку к тестируемому объекту, подключить сигналы для тестирования, вызвать событие вызвать обработчик события или вызвать сигнал вручную, а также запишите установленные тестовые обработчики, которые взаимодействуют с тестовой средой, прежде чем возвращать выполнение к точке, в которой было запущено событие. Что QTest приобретает нас здесь?
(Также размещено на Форумы Qt)
Работа с синхронными событиями с использованием qtestlib
это немного сложно. Если вы посмотрите на источники qtestlib
Вы можете найти, что моделирование событий довольно просто. Так, qtestlib
не предоставляет никаких методов для обработки синхронных событий. В любом случае, вы можете обрабатывать модальные окна Qt, которые создаются вашим приложением.
Основное замечание к этому вопросу заключается в том, что объекты GUI не могут быть доступны из других потоков, кроме потока GUI. И более того, GUI может быть создан только в потоке, где QApplication
был создан. Так что некоторые хитрости, такие как создание новой темы, чтобы нажать кнопку ОК в QMessageBox
будет неудачным с ошибкой вроде this object can not be accessed from other thread
где-то в QWidget
источники.
Чтобы избежать этого случая, асинхронное событие может быть запущено с помощью механизма Qt slots. Прежде всего вы должны определить объект Helper с некоторым слотом, например
class Helper {
Helper() {}
public slots:
doSmth();
}
Далее вы должны создать экземпляр этого объекта в тестовом примере
void BlahblahTest::testCase1() {
Helper h;
...
И прежде чем вызвать какое-то синхронное событие, например, QTest::mouseClick
установите отложенное действие с помощью
QTimer::singleShot(delay, &h, SLOT(doSmth));
Зависит от ваших потребностей реализация doSmth
может быть таким
void Helper::doSmth() {
QList<QWidget *> tlw = qApp()->topLevelWidgets();
foreach (QWidget *w, tlw) {
if (...) { // w is a messagebox
Qt::keyClick(w, Qt::Key_Enter);
}
}
}
Других решений пока нет …