-1

我正在开发一个用 C++ 编写的现有项目,应用程序的入口点是:

QTEST_MAIN(className)

我读过的文档中,这将创建一个标准的 Cmain()函数,但是对于如何调用应用程序测试或调用顺序或它的设置方式完全不清楚。

查看我拥有的项目中的类,没有类构造函数;类本身是从 QObject 派生的。它有 23 个私有插槽:其中一个称为“initTestCase”;其他是各种测试都以“测试”结尾。

插槽“InitTestCase”包含一个设置日志过滤规则的调用,仅此而已。编译并运行项目时,它会执行测试,但我看不到订单的来源或来源。

QTEST_MAIN在我的程序中实际做了什么,插槽是如何设置的,它如何知道要执行哪些测试?

4

1 回答 1

0

QTEST_MAIN 转发到 QTEST_MAIN_IMPL:

#define QTEST_MAIN(TestObject) \
int main(int argc, char *argv[]) \
{ \
    QTEST_MAIN_IMPL(TestObject) \
}

这个 QTEST_MAIN_IMPL 根据您需要的 QApplication(Widgets、Gui 或 Core)而有所不同。对于小部件,它看起来像这样:

#define QTEST_MAIN_IMPL(TestObject) \
    TESTLIB_SELFCOVERAGE_START(#TestObject) \
    QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<TestObject>(); \
    QApplication app(argc, argv); \
    app.setAttribute(Qt::AA_Use96Dpi, true); \
    QTEST_DISABLE_KEYPAD_NAVIGATION \
    TestObject tc; \
    QTEST_SET_MAIN_SOURCE_PATH \
    return QTest::qExec(&tc, argc, argv);

QTest::qExec 定义为qtestcase.cpp

int QTest::qExec(QObject *testObject, int argc, char **argv)
{
    qInit(testObject, argc, argv);
    int ret = qRun();
    qCleanup();
    return ret;
}

qInit () 中,设置了 currentTestObject。

qRun () 中,创建了一个TestMethods实例,它的构造函数,我们发现这个循环:

const QMetaObject *metaObject = o->metaObject();
const int count = metaObject->methodCount();
m_methods.reserve(count);
for (int i = 0; i < count; ++i) {
     const QMetaMethod me = metaObject->method(i);
     if (isValidSlot(me))
         m_methods.push_back(me);
}

isValidSlot()是这样实现的:

static bool isValidSlot(const QMetaMethod &sl)
{
    if (sl.access() != QMetaMethod::Private || sl.parameterCount() != 0
        || sl.returnType() != QMetaType::Void || sl.methodType() != QMetaMethod::Slot)
        return false;
    const QByteArray name = sl.name();
    return !(name.isEmpty() || name.endsWith("_data")
        || name == "initTestCase" || name == "cleanupTestCase"
        || name == "init" || name == "cleanup");
}

最后,调用TestMethods::invokeMethod()显式检查initTestCase第一个并运行它:

QTestResult::setCurrentTestFunction("initTestCase");
if (m_initTestCaseDataMethod.isValid())
    m_initTestCaseDataMethod.invoke(testObject, Qt::DirectConnection);

同样,它在最后进行检查cleanupTestCase

于 2020-01-30T08:53:24.343 回答