添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
void myFirstTest() { QVERIFY(true); // check that a condition is satisfied QCOMPARE(1, 1); // compare two values void mySecondTest() { QVERIFY(myCondition()); QVERIFY(1 != 2); void cleanupTestCase() { qDebug("Called after myFirstTest and mySecondTest.");

如果测试类具有静态公共 void initMain() 方法,则在实例化 QApplication 对象之前, QTEST_MAIN 宏将调用该方法。例如,这允许设置应用程序属性,例如 Qt :: AA_DisableHighDpiScaling 。这是在5.14中添加的。

可以看qt-everywhere-src-5.12.8\qtbase\src\testlib\qtest.h

#define QTEST_MAIN(TestObject) \
QT_BEGIN_NAMESPACE \
QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \
QT_END_NAMESPACE \
int main(int argc, char *argv[]) \
    QApplication app(argc, argv); \
    app.setAttribute(Qt::AA_Use96Dpi, true); \
    QTEST_DISABLE_KEYPAD_NAVIGATION \
    QTEST_ADD_GPU_BLACKLIST_SUPPORT \
    TestObject tc; \
    QTEST_SET_MAIN_SOURCE_PATH \
    return QTest::qExec(&tc, argc, argv); \

既可以手动写main也可以直接在测试类后加QTEST_MAIN(testclass)

可以定义如下的private slot可以在当前整个测试前后或每个用例测试前后进行一些资源初始化和释放。

  • initTestCase_data() 将被调用以创建全局测试数据表。
  • initTestCase() 将在第一个测试功能执行之前被调用。
  • cleanupTestCase() 在最后一个测试函数执行后将被调用。
  • init() 将在每个测试功能执行之前被调用。
  • cleanup() 将在每个测试函数之后调用。
  • 使用RAII(资源获取是初始化),并在析构函数中调用清除操作,以确保它们在测试函数返回且对象移出作用域时发生。即也可以自己写构造析构来进行部分资源的申请和释放。

    QT_KEYPAD_NAVIGATION

    #ifdef QT_KEYPAD_NAVIGATION
    #  define QTEST_DISABLE_KEYPAD_NAVIGATION QApplication::setNavigationMode(Qt::NavigationModeNone);
    #else
    #  define QTEST_DISABLE_KEYPAD_NAVIGATION
    #endif
    

    枚举Qt :: NavigationMode,此枚举类型描述移动焦点的模式。

    Qt::NavigationModeKeypadDirectional Qt :: Key_UpQt :: Key_DownQt :: Key_LeftQt :: Key_Right用于更改焦点。 Qt::NavigationModeCursorAuto 鼠标光标用于更改焦点,仅在非触摸屏设备上显示。除非设备具有模拟鼠标类型的输入设备(例如触摸板),否则小键盘用于实现虚拟光标。对于需要同时在触摸和非触摸设备上进行指针控制的Web浏览器之类的应用程序,建议使用此设置。 Qt::NavigationModeCursorForceVisible 鼠标光标用于更改焦点,无论设备类型如何,鼠标光标都会显示。键盘用于实现虚拟光标,除非设备具有模拟鼠标类型的输入设备(例如触摸板)

    即由QT_KEYPAD_NAVIGATION宏定义是否禁用键盘鼠标(仅使用触摸屏)

    app.setAttribute(Qt::AA_Use96Dpi, true);

    Qt::AA_Use96Dpi 假定屏幕的分辨率为96 DPI,而不是使用操作系统提供的分辨率。这将导致字体渲染在设备上的每像素像素一致,而不是将1点定义为1/72英寸。

    QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS

    #ifndef QT_NO_OPENGL
    #  define QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \
        extern Q_TESTLIB_EXPORT std::set<QByteArray> *(*qgpu_features_ptr)(const QString &); \
        extern Q_GUI_EXPORT std::set<QByteArray> *qgpu_features(const QString &);
    #  define QTEST_ADD_GPU_BLACKLIST_SUPPORT \
        qgpu_features_ptr = qgpu_features;
    #else
    #  define QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
    #  define QTEST_ADD_GPU_BLACKLIST_SUPPORT
    #endif
    

    QTEST_SET_MAIN_SOURCE_PATH

    #ifdef QT_TESTCASE_BUILDDIR
    #  define QTEST_SET_MAIN_SOURCE_PATH  QTest::setMainSourcePath(__FILE__, QT_TESTCASE_BUILDDIR);
    #else
    #  define QTEST_SET_MAIN_SOURCE_PATH  QTest::setMainSourcePath(__FILE__);
    #endif
    

    ->void QTest::setMainSourcePath(const char *file, const char *builddir)

    ->>QTest::mainSourcePath = fi.absolutePath();

    ->>>static QString mainSourcePath;

    QT源码qtest库Demo

    下面几个是源qt-everywhere-src-5.12.8\qtbase\examples\qtestlib中的几个demo,工程是QT工程。

    tutorial1.pro

    QT += widgets testlib
    SOURCES = testqstring.cpp
    # install
    target.path = $$[QT_INSTALL_EXAMPLES]/qtestlib/tutorial1
    INSTALLS += target
    

    testqstring.cpp

    //! [0]
    #include <QtTest/QtTest>
    class TestQString: public QObject
        Q_OBJECT
    private slots:
        void toUpper();
    //! [0]
    //! [1]
    void TestQString::toUpper()
        QString str = "Hello";
        QCOMPARE(str.toUpper(), QString("HELLO"));
    //! [1]
    //! [2]
    QTEST_MAIN(TestQString)
    #include "testqstring.moc"
    //! [2]
    

    tutorial2.pro

    QT += widgets testlib
    SOURCES = testqstring.cpp
    # install
    target.path = $$[QT_INSTALL_EXAMPLES]/qtestlib/tutorial2
    INSTALLS += target
    

    testqstring.cpp

    #include <QtTest/QtTest>
    //! [0]
    class TestQString: public QObject
        Q_OBJECT
    private slots:
        void toUpper_data();
        void toUpper();
    //! [0]
    //! [1]
    void TestQString::toUpper_data()
        QTest::addColumn<QString>("string");
        QTest::addColumn<QString>("result");
        QTest::newRow("all lower") << "hello" << "HELLO";
        QTest::newRow("mixed")     << "Hello" << "HELLO";
        QTest::newRow("all upper") << "HELLO" << "HELLO";
    //! [1]
    //! [2]
    void TestQString::toUpper()
        QFETCH(QString, string);
        QFETCH(QString, result);
        QCOMPARE(string.toUpper(), result);
    //! [2]
    //! [3]
    QTEST_MAIN(TestQString)
    #include "testqstring.moc"
    //! [3]
    

    tutorial3.pro

    QT += widgets testlib
    SOURCES = testgui.cpp
    # install
    target.path = $$[QT_INSTALL_EXAMPLES]/qtestlib/tutorial3
    INSTALLS += target
    

    testgui.cpp

    //! [0]
    #include <QtWidgets>
    #include <QtTest/QtTest>
    class TestGui: public QObject
        Q_OBJECT
    private slots:
        void testGui();
    //! [0]
    //! [1]
    void TestGui::testGui()
        QLineEdit lineEdit;
        QTest::keyClicks(&lineEdit, "hello world");
        QCOMPARE(lineEdit.text(), QString("hello world"));
    //! [1]
    //! [2]
    QTEST_MAIN(TestGui)
    #include "testgui.moc"
    //! [2]
    

    tutorial4.pro

    QT += widgets testlib
    SOURCES = testgui.cpp
    # install
    target.path = $$[QT_INSTALL_EXAMPLES]/qtestlib/tutorial4
    INSTALLS += targe
    

    testgui.cpp

    #include <QtWidgets>
    #include <QtTest/QtTest>
    //! [0]
    class TestGui: public QObject
        Q_OBJECT
    private slots:
        void testGui_data();
        void testGui();
    //! [0]
    //! [1]
    void TestGui::testGui_data()
        QTest::addColumn<QTestEventList>("events");
        QTest::addColumn<QString>("expected");
        QTestEventList list1;
        list1.addKeyClick('a');
        QTest::newRow("char") << list1 << "a";
        QTestEventList list2;
        list2.addKeyClick('a');
        list2.addKeyClick(Qt::Key_Backspace);
        QTest::newRow("there and back again") << list2 << "";
    //! [1]
    //! [2]
    void TestGui::testGui()
        QFETCH(QTestEventList, events);
        QFETCH(QString, expected);
        QLineEdit lineEdit;
        events.simulate(&lineEdit);
        QCOMPARE(lineEdit.text(), expected);
    //! [2]
    //! [3]
    QTEST_MAIN(TestGui)
    #include "testgui.moc"
    //! [3]
    

    tutorial5.pro

    QT += widgets testlib
    SOURCES = benchmarking.cpp
    # install
    target.path = $$[QT_INSTALL_EXAMPLES]/qtestlib/tutorial5
    INSTALLS += target
    

    benchmarking.cpp

    #include <QtWidgets>
    #include <qtest.h>
    class TestBenchmark : public QObject
        Q_OBJECT
    private slots:
        void simple();
        void multiple_data();
        void multiple();
        void series_data();
        void series();
    //! [0]
    void TestBenchmark::simple()
        QString str1 = QLatin1String("This is a test string");
        QString str2 = QLatin1String("This is a test string");
        QCOMPARE(str1.localeAwareCompare(str2), 0);
        QBENCHMARK {
            str1.localeAwareCompare(str2);
    //! [0]
    //! [1]
    void TestBenchmark::multiple_data()
        QTest::addColumn<bool>("useLocaleCompare");
        QTest::newRow("locale aware compare") << true;
        QTest::newRow("standard compare") << false;
    //! [1]
    //! [2]
    void TestBenchmark::multiple()
        QFETCH(bool, useLocaleCompare);
        QString str1 = QLatin1String("This is a test string");
        QString str2 = QLatin1String("This is a test string");
        int result;
        if (useLocaleCompare) {
            QBENCHMARK {
                result = str1.localeAwareCompare(str2);
        } else {
            QBENCHMARK {
                result = (str1 == str2);
        Q_UNUSED(result);
    //! [2]
    //! [3]
    void TestBenchmark::series_data()
        QTest::addColumn<bool>("useLocaleCompare");
        QTest::addColumn<int>("stringSize");
        for (int i = 1; i < 10000; i += 2000) {
            QByteArray size = QByteArray::number(i);
            QTest::newRow(("locale aware compare--" + size).constData()) << true << i;
            QTest::newRow(("standard compare--" + size).constData()) << false << i;
    //! [4]
    //! [5]
    void TestBenchmark::series()
        QFETCH(bool, useLocaleCompare);
        QFETCH(int, stringSize);
        QString str1 = QString().fill('A', stringSize);
        QString str2 = QString().fill('A', stringSize);
        int result;
        if (useLocaleCompare) {
            QBENCHMARK {
                result = str1.localeAwareCompare(str2);
        } else {
            QBENCHMARK {
                result = (str1 == str2);
        Q_UNUSED(result);
    //! [5]
    QTEST_MAIN(TestBenchmark)
    #include "benchmarking.moc"
    

    命令行测试

    /myTestDirectory$ testQString toUpper
    /myTestDirectory$ testQString toUpper toInt:zero
    /myTestDirectory$ testMyWidget -vs -eventdelay 500
    

    可以指定单个用例进行测试,可以带参数(没用过),还可以指定鼠标键盘事件的延时触发(没用过)

    可以参考命令行测试选项

    测试API

    QTest Namespace

    CMake编译

    如果需要转成CMake,参考[Cmake编译QT项目](https://blog.csdn.net/bbdxf/article/details/82988468)。

    需要注意用了set(CMAKE_AUTOMOC ON),就不能用qt5_wrap_cpp(MOC ${HEAD_FILES})了否则可能报错。

    # AUTOMOC是一个布尔值,指定CMake是否将moc 自动处理Qt预处理程序,
    # 即无需使用 QT4_WRAP_CPP()或QT5_WRAP_CPP()宏。当前支持Qt4和Qt5。
    set(CMAKE_AUTOMOC ON) 
    # AUTOUIC是一个布尔值,指定CMake是否自动处理Qt uic代码生成器,
    # 即不必使用QT4_WRAP_UI()或QT5_WRAP_UI()宏。当前支持Qt4和Qt5。
    set(CMAKE_AUTOUIC ON)
    # AUTORCC是一个布尔值,指定CMake是否将rcc自动处理Qt代码生成器,
    # 即无需使用QT4_ADD_RESOURCES()或QT5_ADD_RESOURCES() 宏。当前支持Qt4和Qt5。
    set(CMAKE_AUTORCC ON)
    # process ui and moc action
    #qt5_wrap_cpp(MOC ${HEAD_FILES})
    qt5_wrap_ui(WRAP_FILES ${UI_FILES})
    # qt5_add_resources(RCC res.qrc) # ${RESOURCE_DIR}
    

    开启全局后,可以直接加入到编译的测试目标中即可

    add_executable(${PROJECT_NAME} ${SRC_FILES} ${UI_FILES} ${QRC_FILE})
    

    注意对应的package和lib名

    find_package(Qt5Test REQUIRED)
    target_link_libraries(mytest PRIVATE Qt5::Test)