3

I did some survey, if it might be possible to use QtTest to test some of my custom Qt Widgets.

I was able to build and run tests and I was also able to simulate events and check them with QSignalSpy.

The widgets I'm going to tests are not revealing their internal subwidgets, so that I have to simulate the positions of my mouse clicks relative to their parent widget.

For some reason I'm failing with this approach. The following snippet shows what I'm trying to achieve.

auto button=new QPushButton("Hello");
auto grpBox = new QGroupBox("Group Box");
grpBox->setLayout(new QVBoxLayout);
grpBox->layout()->addWidget(button);
QSignalSpy spy(button, &QPushButton::clicked);
grpBox->show();
QTest::mouseClick(button, Qt::MouseButton::LeftButton);
QTest::mouseClick(grpBox, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier, QPoint(250,70));
QCOMPARE(spy.count(), 2); // 1!=2

The first click is considered correctly, whereas the second one vanishes somehow. Why is that?

I'm wondering, if I really understood how to use the framework correctly, as dealing with mouse positions, seems to be too tedious and fragile for a practical test framework.

Revision:

It's obvious that using coordinates in a GUI test are very fragile. Hence, I found a solution utilizing findChild that actually does the same thing.

auto button=new QPushButton("Hello");
button->setObjectName("PushButton");
auto grpBox = new QGroupBox("Group Box");
grpBox->setLayout(new QVBoxLayout);
grpBox->layout()->addWidget(button);
QSignalSpy spy(button, &QPushButton::clicked);
grpBox->show();
QTest::mouseClick(button, Qt::MouseButton::LeftButton);
if (auto btn = grpBox->findChild<QPushButton*>("PushButton")) {
    QTest::mouseClick(btn, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier);
} else {
    QVERIFY(false);
}
QCOMPARE(spy.count(), 2);

This combines two advantages. Firstly, it is no longer necessary to deal with coordinates and secondly you still doesn't need to touch the code of the widgets you are going to test.

For this approach it seems to be advantageous, if every gui element has a unique objectName() supporting an easy search mechanism.

Aleph0
  • 5,816
  • 4
  • 29
  • 80
  • What makes you so sure that `QPoint(250,70)` is not outside of the QGroupBox? – JefGli Jun 09 '16 at 12:34
  • Actually, I made a screenshot of the client area of the window. I then used IrfanView to select the point. After doing it again it seems that I picked the wrong point, it should be more like `QPoint(50, 37)`. Still, the test is failing. Yesterday I also found a working solution by myself utilizing the functions `findChild`, which seems to be more reasonable. Especially, if you change the widget layout more often. – Aleph0 Jun 10 '16 at 06:10
  • I like your solution, but I would personally move `grpBox->findChild` out of the `mouseClick` and check it for `nullptr` first, as the behavior for providing a `nullptr` is undocumented. Instead of crashing the full testing environment, you will simply fail the test that way. – JefGli Jun 10 '16 at 06:24
  • That is a very good idea. Many thanks. I'll change my posted code accordingly. Still I'm puzzled why my previous code didn't worked. Maybe the coordinates are still wrong. – Aleph0 Jun 10 '16 at 06:26

0 Answers0