gpt4 book ai didi

c++ - 如何运行多个 QTest 类?

转载 作者:可可西里 更新时间:2023-11-01 16:14:21 29 4
gpt4 key购买 nike

我有一个子项目,我将所有 QTest 单元测试放在其中,并构建一个运行测试的独立测试应用程序(即我从 Qt Creator 中运行它)。我有多个可以使用 qExec() 执行的测试类。但是我不知道执行多个测试类的正确方法是什么。

目前我是这样做的(MVCE):

测试.pro

QT -= gui
QT += core \
testlib

CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
TARGET = testrunner

HEADERS += test_foo.h
SOURCES += main.cpp

main.cpp

#include <QtTest>
#include <QCoreApplication>
#include "test_foo.h"

int main(int argc, char** argv) {
QCoreApplication app(argc, argv);

TestFooClass testFoo;
TestBarClass testBar;
// NOTE THIS LINE IN PARTICULAR.
return QTest::qExec(&testFoo, argc, argv) || QTest::qExec(&testBar, argc, argv);
}

test_foo.h

#include <QtTest>

class TestFooClass: public QObject
{
Q_OBJECT
private slots:
void test_func_foo() {};
};

class TestBarClass: public QObject
{
Q_OBJECT
private slots:
void test_func_bar() {};
};

然而 documentation for qExec()说这是错误的方式:

For stand-alone test applications, this function should not be called more than once, as command-line options for logging test output to files and executing individual test functions will not behave correctly.

另一个主要缺点是没有针对所有测试类的单一摘要,仅针对个别类。当我有几十个类,每个类都有几十个测试时,这是一个问题。要检查是否所有测试都通过了,我必须向上滚动以查看每个类通过/失败的所有“总计”,例如:

********* Start testing of TestFooClass *********
PASS : TestFooClass::initTestCase()
PASS : TestFooClass::test_func_foo()
PASS : TestFooClass::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted
********* Finished testing of TestFooClass *********
********* Start testing of TestBarClass *********
PASS : TestBarClass::initTestCase()
PASS : TestBarClass::test_func_bar()
PASS : TestBarClass::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted
********* Finished testing of TestBarClass *********

我也很惊讶我的qExec() || qExec() 考虑到 documentation 有效说如果测试失败 qExec() 返回一个非零值,这应该意味着以下所有 qExec() 调用都不会发生,但这似乎不是情况。

运行多个测试类的正确方法是什么?这样我就可以一眼看出我的数百个单元测试是否失败。

最佳答案

我曾经找到一个不错的solution使用普通 Qt 项目(no TEMPLATE = subdirs),该项目使用宏方法 创建主函数并自动注册所有测试类( )也只有一个简单的辅助头文件。

这是一个示例测试类(只有相关的头文件):

#ifndef FOOTESTS_H
#define FOOTESTS_H

#include "AutoTest.h"

class FooTests : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void test1();
void test2();
void cleanupTestCase();
};

DECLARE_TEST(FooTests)

#endif // FOOTESTS_H

和 main,它使用以这种方式创建的每个测试类:

#include "AutoTest.h"

TEST_MAIN

AutoTest.h代码:

#ifndef AUTOTEST_H
#define AUTOTEST_H

#include <QTest>
#include <QList>
#include <QString>
#include <QSharedPointer>

namespace AutoTest
{
typedef QList<QObject*> TestList;

inline TestList& testList()
{
static TestList list;
return list;
}

inline bool findObject(QObject* object)
{
TestList& list = testList();
if (list.contains(object))
{
return true;
}
foreach (QObject* test, list)
{
if (test->objectName() == object->objectName())
{
return true;
}
}
return false;
}

inline void addTest(QObject* object)
{
TestList& list = testList();
if (!findObject(object))
{
list.append(object);
}
}

inline int run(int argc, char *argv[])
{
int ret = 0;

foreach (QObject* test, testList())
{
ret += QTest::qExec(test, argc, argv);
}

return ret;
}
}

template <class T>
class Test
{
public:
QSharedPointer<T> child;

Test(const QString& name) : child(new T)
{
child->setObjectName(name);
AutoTest::addTest(child.data());
}
};

#define DECLARE_TEST(className) static Test<className> t(#className);

#define TEST_MAIN \
int main(int argc, char *argv[]) \
{ \
return AutoTest::run(argc, argv); \
}

#endif // AUTOTEST_H

所有学分转到Rob Caldecott .

关于c++ - 如何运行多个 QTest 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37987301/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com