我做了一些调查,是否可以使用 QtTest 来测试我的一些自定义 Qt 小部件。
我能够构建和运行测试,还能够模拟事件并使用QSignalSpy
.
我要测试的小部件不会显示它们的内部子小部件,因此我必须模拟鼠标点击相对于它们的父小部件的位置。
出于某种原因,我在这种方法上失败了。以下代码段显示了我想要实现的目标。
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
第一次点击被认为是正确的,而第二次点击却以某种方式消失了。这是为什么?
我想知道,如果我真的了解如何正确使用框架,处理鼠标位置,对于实际的测试框架来说似乎太乏味和脆弱了。
修订:
很明显,在 GUI 测试中使用坐标是非常脆弱的。因此,我找到了一个解决方案,利用findChild
它实际上做同样的事情。
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);
这结合了两个优点。首先,不再需要处理坐标,其次您仍然不需要触摸要测试的小部件的代码。
objectName()
对于这种方法,如果每个 gui 元素都有一个独特的支持简单搜索机制,这似乎是有利的。