【问题标题】:Qt QML Unit test setup using Cmake使用 Cmake 设置 Qt QML 单元测试
【发布时间】:2020-12-23 18:17:10
【问题描述】:

我正在尝试使用 QtQuickTest 进行单元测试,但我收到了一些错误,并且在将它们包含在其他测试中时也遇到了一些问题。

基本上我的 tst_mytest.cpp 文件看起来像这样,取自:https://doc.qt.io/qt-5/qtquicktest-index.html

// tst_mytest.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 "tst_mytest.moc"

现在这个宏 QUICK_TEST_MAIN_WITH_SETUP 运行 main 函数,这意味着我不能在这个 .exe 文件中自己运行它(至少我尝试过并且失败了),然后我只能为引擎设置上下文。

我的 cmake 看起来像这样:

set(TEST_QML_EXE "${PROJECT_NAME}_QML_TEST")

add_executable(${TEST_QML_EXE})

target_sources(${TEST_QML_EXE}
PRIVATE
    qml/tst_TestMain.cpp
)

set_property(TARGET ${TEST_QML_EXE} PROPERTY ${PROJECT_NAME}_PRIVATE 1)

target_link_libraries(${TEST_QML_EXE}
PRIVATE
    Qt5::Core
    Qt5::Quick
    Qt5::QuickControls2
    Qt5::QuickTest  
    Qt5::Qml
)

当我运行它时,我得到了

onecore\com\combase\objact\objact.cxx(836)\combase.dll!00007FFA0677B2D7: (caller: 00007FFA0677A15C) ReturnHr(399) tid(1498) 800401F0 CoInitialize has not been called.
onecore\com\combase\objact\objact.cxx(836)\combase.dll!00007FFA0677B2D7: (caller: 00007FFA0677A15C) ReturnHr(400) tid(1498) 800401F0 CoInitialize has not been called.
onecore\com\combase\objact\objact.cxx(836)\combase.dll!00007FFA0677B2D7: (caller: 00007FFA0677A15C) ReturnHr(401) tid(1498) 800401F0 CoInitialize has not been called.
onecore\com\combase\objact\objact.cxx(836)\combase.dll!00007FFA0677B2D7: (caller: 00007FFA0677A15C) ReturnHr(402) tid(1498) 800401F0 CoInitialize has not been called.
onecore\com\combase\objact\objact.cxx(836)\combase.dll!00007FFA0677B2D7: (caller: 00007FFA0677A15C) ReturnHr(403) tid(1498) 800401F0 CoInitialize has not been called.
onecore\com\combase\objact\objact.cxx(836)\combase.dll!00007FFA0677B2D7: (caller: 00007FFA0677A15C) ReturnHr(404) tid(1498) 800401F0 CoInitialize has not been called.

...重复错误。

到目前为止,我发现这似乎与不打开应用程序实例来运行测试有关,尽管我在与 tst_*.cpp 文件相同的文件夹中创建的 QML 测试运行,但我只是得到了所有每个文件都会出现这些重复错误。

现在,如果我知道如何运行 QUICK_TEST_MAIN_WITH_SETUP 宏而不包含它的 MAIN 部分,这样我就可以在自定义主程序中启动 QCoreApplication,我认为重复错误可能会消失,也许我可以运行所有后端测试在同一个可执行文件中,这将是完美的。

感谢任何帮助

【问题讨论】:

    标签: c++ qt unit-testing cmake qml


    【解决方案1】:

    你需要调用CoInitialize(nullptr);来初始化COM。
    COM = https://en.wikipedia.org/wiki/Component_Object_Model

    【讨论】:

    • 我试图在我的 Setup 类的构造函数中调用它,但我仍然得到相同的重复错误。
    • 您需要在使用其他任何使用 COM 的东西之前调用它。它的作用是加载使用 COM 所需的 dll 文件。如果您的构造函数在第一个基于 COM 的功能之后运行,那么它将不起作用 如果您在构造函数中调用它,它可能会被多次调用?你只需要调用 CoInitialize(nullptr);在启动时,然后将 else 用于 COM 工作
    • 感谢您的持续回复。我明白这个 CoInitialize(nullptr);应该这样做,而且似乎放置它的最佳位置是在 main 的开头。我的问题是我正在尝试使用运行自己的主循环的 Qt Quick Test 宏 QUICK_TEST_MAIN_WITH_SETUP(甚至没有 SETUP,同样的问题),因此我似乎无法让它执行 CoInitialize(nullptr);任何地方,因为我对测试框架的唯一影响是通过 Setup 类。有什么办法吗?
    • 我搜索了宏,这可能类似? code.woboq.org/qt5/qtdeclarative/src/qmltest/quicktest.h.html 。如果您编写相同的代码但添加 CoInitialize(nullptr);首先和最后你应该打电话给CoUninitialize();。我还没有使用过 Qt 及其测试逻辑,但应该可以编写自己的 main。大多数人需要编写代码来初始化测试,所有测试框架都允许这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    相关资源
    最近更新 更多