如何模拟QML组件
How to mock a QML component
实际上,我正试图在嵌入C++对象的QML组件上运行一些测试。不幸的是,我在执行测试时遇到了一些错误。QML文件无法识别C++对象。这也是有意义的,因为C++对象是在main.cpp文件中设置的。
我的问题是:如何模拟上下文属性来执行QML测试?或者其他人说,如何混合Qt/QML代码进行单元测试?
我在没有编译任何C++代码的情况下就完成了QML测试。
在我的例子中,我有一个C++对象控制器,它有一个名为left_motor的属性,这是另一个对象,它有speed属性。
请注意speed是可读的,但不是可写的。任何更新都将通过插槽进行。在QML中,它看起来像这样:controller.left_motor.onGuiSpeedChanged(速度)
我能够在QML中使用Item组件、属性和一些javascript来模拟这一点。
Item { // mock of controller id: controller property alias left_motor: left_motor Item { id: left_motor property int speed: 0 function onGuiSpeedChanged(arg) { speed = arg } } } property alias controller: controller
现在调用controller.left_motor.onGuiSpeedChanged(速度)像以前一样解析,但连接到mock函数。我甚至可以读回speed属性来知道呼叫发生了。
这是我的测试函数(我正在测试的代码是第1页的一部分):
function test_set_speed() { console.log("controller.left_motor.speed: " + controller.left_motor.speed) var got = page1.set_left_speed(250) compare(got, 250, "set_left_speed() return incorrect") console.log("controller.left_motor.speed: " + controller.left_motor.speed) }
请注意,使用插槽而不是可写属性非常重要。对槽的调用看起来就像一个函数调用,可以被嘲笑为这样。我想不出一个方法来模拟一个地产写作。
我开始尝试可写属性,因为这是绑定C++和QML的文档中的第一件事。它按预期连接QML和C++,但无法进行模拟测试。
据我所知,你们和我遇到了同样的问题。不久前,我写了这个mock:https://bitbucket.org/troyane/qml-cpp-template(您可以出于自己的目的免费使用该代码)。
看看main.cpp
,你可以看到两种做事的方法:
// 1 case:
// Register type and create object at QML side
qmlRegisterType<CppClass>("CppClassModule", 1, 0, "CppClass");
QQmlApplicationEngine engine(QUrl("qrc:///qml/main.qml"));
qDebug() << "Qt version: " << qVersion();
// 2 case:
// Create object here and "move it up" to QML side
// engine.rootContext()->setContextProperty("cppClass", new CppClass);
祝你好运!
最好的解决方案是将C++类型移动到QML插件中,以便QML测试可以导入它们。这个插件需要在运行时可用于测试,这意味着确保可以在导入路径中找到它们。如果遇到找不到插件的任何问题,可以将QML_IMPORT_TRACE
环境变量设置为1
,以提供一些有用的调试输出。
然而,即使是仅QML的测试用例也需要一些C++来设置它们。
要在运行任何QML测试之前执行C++代码,可以使用QUICK_TEST_MAIN_WITH_SETUP
宏:
// src_qmltest_qquicktest.cpp
#include <QtQuickTest>
#include <QQmlEngine>
#include <QQmlContext>
class Setup : public QObject
{
Q_OBJECT
public:
Setup() {}
public slots:
void qmlEngineAvailable(QQmlEngine *engine)
{
engine->rootContext()->setContextProperty("myContextProperty", QVariant(true));
}
};
QUICK_TEST_MAIN_WITH_SETUP(mytest, Setup)
#include "src_qmltest_qquicktest.moc"
最灵活、最强大的选择是用C++编写测试并从中加载QML。
- 基于 QML 模型的组件在 android 上具有未定义的 modelData
- 是否可以从C++创建 Qml 组件?
- 如何在 QML 组件中使用 C++ 类
- QML 如何捕获组件转换更改
- Qml:从文件加载组件时将参数作为 URL 的一部分传递
- QML组件与信号连接
- 从C++访问现有的 QML 组件
- 如何将本机窗口嵌入到 QML 组件中
- QML:如何将动态创建的组件与自定义的内部对象一起使用
- 如何在 QML 中实例化C++组件 - WITH 参数化构造函数
- QtQuick:QQmlApplicationEngine无法加载组件qrc:/main.qml:23附加对象分配无效
- qml桌面组件扩展
- QML 从C++在加载器中动态插入组件
- 如何使用 qml 组件(不带 C++)创建插件的 deb 包
- QML:如何在不实际移动任何可见组件的情况下,在鼠标Aeria顶部获取鼠标移动的方向
- 无法更改从C++动态创建的 QML 组件的属性
- 设计Qml桌面组件的样式
- 从c++中与Repeater中委托的QML组件进行交互
- QML组件'Video'无法播放Qt资源文件中的视频文件
- 如何模拟QML组件