[Development] QTestlib: how not to test mouseMoveEvent handling

Shawn Rutledge Shawn.Rutledge at qt.io
Mon Jul 8 17:38:07 CEST 2019


> On 8 Jul 2019, at 16:24, Volker Hilsheimer <volker.hilsheimer at qt.io> wrote:
> 
> Hi,
> 
> 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.

Yep.  Cursor support can be disabled, I think that’s one reason at least.  Another is that some platforms (i.e. Wayland) don’t allow applications to set cursor position.  Anyway it’s heavy-handed and slow.  But tests that need to simulate mouse hover or mouse enter/exit by sending events do need to ensure that the cursor is _not_ on top of the window, to avoid getting spurious events… and that’s usually done by QCursor::setPos(); so we can’t seem to get rid of it after all.

https://codereview.qt-project.org/c/qt/qtbase/+/5290 seems to have put it into its current state… it’s old.  But before that was https://codereview.qt-project.org/c/qt/qtbase/+/4462 which comments out QCursor::setPos() and sends a platform event instead… at least in one case.  Too bad the commit message is so sparse.

I suppose there’s the usual tradeoff between the philosophy that real platform testing should involve real platform events (in this case: if you really move the system mouse cursor, then the window system will hopefully send a mouse move event to the window, and aren’t you making the test more realistic that way?) vs. the practical tendency for that kind of testing to be less reliable, with unpredictable latency, needing to use QTRY_ much more because you don’t know how long to wait until the window system reacts, etc.



More information about the Development mailing list