[Development] QTestlib: how not to test mouseMoveEvent handling

Volker Hilsheimer volker.hilsheimer at qt.io
Mon Jul 8 16:24:59 CEST 2019


Executive summary:

* QTest::mouseMove seems to be broken
* when simulating QEvent::MouseMove events by constructing event objects, always construct them with global position

The details:

While trying to fix https://bugreports.qt.io/browse/QTBUG-76765 to not update the mouse cursor when the cursor-fied QGraphicsItem the mouse is on top of is disabled, I noticed the following pattern in the respective test:

QTest::mouseMove(localPoint, widget);
QMouseEvent event(QEvent::MouseMove, localPoint, Qt::NoButton, 0, 0);
QApplication::sendEvent(widget, &event);

which confused me a bit. Shouldn’t QTest::mouseMove already have sent the event? Apparently not. That there is no overload that takes modifiers and keys is also strange.

In the end, when running the test locally on my Mac, I never got it ot pass.

What seems to happen is this:

* for QWidget receivers, QTest::mouseMove just calls QCursor::setPos

QCursor::setPos is not guaranteed to generate mouse events. The documentation of some overloads of that function [1] in fact explicitly advises against using that function in unit tests.

* QMouseEvent uses QCursor::pos if no global position has been explicitly provided

A lot of tests don’t explicitly calculate and provide the global mouse position, but some widgets use the global position (QGraphicsView, for instance).

Since QCursor::setPos doesn’t do much of anything on my mac when I’m logged in (the visible mouse pointer on the screen didn’t move when running tests), the mouse events received are not the ones the test expects to be received, and the tests fail.

I tried to fix this case now by always constructing QMouseEvent objects with both local and global positions. That is easy, but a bit tedious, and that we don’t use QTest::mouseMove suggests that this function has not been working as one would expect for a while.

Perhaps someone can enlighten me why QTest::mouseMove doesn’t simulate a QEvent like QTest::mousePress does? An overload that takes modifiers and keys, and simply simulates the event, would be a good addition, perhaps?


[1] https://doc.qt.io/qt-5/qcursor.html#setPos-1

More information about the Development mailing list