понедельник, 16 июля 2012 г.

Тестирование событий мыши с помощью QTestLib

Несколько месяцев назад я писал про тестирование виджетов на форме и появляющихся диалогов. Теперь же я столкнулся с трудностями тестирования мышевозства.

В качестве тестового примера выбрана форма с двумя списками, в которую мы добавим возможность добавлять элементы из одного списка в другой.

Начнем с простого примера тестирования событий мыши - mouseClick.
 1 #include <QtTest/QtTest>
 2 #include "ui_TwoListsForm.h"
 3 #include "TwoListsForm.h"
 4 
 5 class TestGui: public QObject
 6 {
 7   Q_OBJECT
 8 
 9 private slots:
10   void FirstListClick()
11   {
12     TwoListsForm frm;
13     Ui_TwoListsForm* ui = frm.GetUi();
14 
15     QRect itemRect = ui->list1->visualItemRect(ui->list1->item(0));
16     QTest::mouseClick(ui->list1->viewport(), Qt::LeftButton, 0, itemRect.center());
17 
18     QVERIFY(ui->list1->currentItem() != NULL);
19     QCOMPARE(ui->list1->currentItem()->text(), QString("Lorem Ipsum"));
20   }
21 };
22 
23 QTEST_MAIN(TestGui)
24 
25 #include "test.moc"
Как и в прошлый раз, получаем ui через метод, доступный только во время тестирования. Затем берем rect для первого элемента в списке и кликаем в его середину. Единственная тонкость в этом примере - отсылать событие нужно не самому лист-виджету, а viewport'у!

Теперь протестируем двойной клик, по которому элемент исчезает из первого списка и появляется во втором:
 1   void FirstListDblClick()
 2   {
 3     TwoListsForm frm;
 4     Ui_TwoListsForm* ui = frm.GetUi();
 5 
 6     QRect itemRect = ui->list1->visualItemRect(ui->list1->item(0));
 7     QTest::mousePress(ui->list1->viewport(), Qt::LeftButton, 0, itemRect.center());
 8     QTest::mouseDClick(ui->list1->viewport(), Qt::LeftButton, 0, itemRect.center());
9 
10     QCOMPARE(ui->list1->count(), 0);
11     QCOMPARE(ui->list2->count(), 1);
12   }
13 };
Здесь "главным хаком" является вызов mousePress перед mouseDClick. Это связано с тем, что QTest отправляет непосредственно двойной клик, но его обработка в QListWidget предполагает, что все же сначала произойдет простое нажатие левой клавиши мыши (QListWidget на этом событии помечает у себя текущий выбранный элемент в списке).

Все мои попытки протестировать drag&drop успехом не увенчались. И, судя по всему, на данный момент это невозможно. Но вроде как что-то сделали для Qt5. Проанализировав код qtest, заметил, что все события мыши, кроме MouseMove, тестируются через симуляцию соответствующих QMouseEvent'ов, а для MouseMove переставляется курсор и вызывает qApp->processEvents(). Т.е. "эмуляция" движения мыши должна быть получена, как системное событие передвижение мыши, а значит тестируемый виджет должен быть активными поверх всех окон.

Итог: все, что связано с кликами и дабл-кликами, в принципе тестируемо, а вот с передвижением мыши все не так гладко.
Исходный код

Комментариев нет:

Отправить комментарий