簡體   English   中英

QTEST_MAIN 如何自動設置一切以運行測試?

[英]How does QTEST_MAIN set everything up automatically to run tests?

我正在處理一個用 C++ 編寫的現有項目,應用程序的入口點是:

QTEST_MAIN(className)

我讀過的文檔中,這將創建一個標准的 C main()函數,但它並不清楚如何調用應用程序測試或調用順序是什么或其設置方式。

看我手頭的項目中的類,沒有類構造函數; 類本身是從 QObject 派生的。 它有 23 個私有槽:其中之一稱為“initTestCase”; 其他的都是以“Test”結尾的各種測試。

插槽“InitTestCase”包含對設置日志過濾規則的單個調用,僅此而已。 當項目編譯並運行時,它會執行測試,但我看不到訂單的來源或方式。

QTEST_MAIN在我的程序中實際做什么,插槽是如何設置的,它如何知道要執行哪些測試?

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM