我做了一些调查,如果有可能使用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

第一次点击被认为是正确的,而第二次点击则以某种方式消失 . 这是为什么?

我想知道,如果我真的理解如何正确使用框架,处理鼠标位置,对于实际的测试框架来说似乎太繁琐和脆弱 .

Revision:

很明显,在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);

这结合了两个优点 . 首先,不再需要处理坐标,其次,您仍然不需要触摸要测试的小部件的代码 .

对于这种方法,如果每个gui元素都具有支持简单搜索机制的唯一 objectName() ,那么这似乎是有利的 .