Split QTest::qExec()

Split into (internal) QTest::qInit(), qRun(), and qCleanup(), that
allow qtquickcontrols2 to initialize the test framework once, repeat
the tests for all built-in styles (Default, Material, Universal), and
finally cleanup things:

    $ ./tst_qquickbutton text
    ********* Start testing of tst_QQuickButton *********
    Config: Using QtTest library 5.10.0, Qt 5.10.0 (...)
    PASS   : tst_QQuickButton::Default::initTestCase()
    PASS   : tst_QQuickButton::Default::text()
    PASS   : tst_QQuickButton::Default::cleanupTestCase()
    PASS   : tst_QQuickButton::Material::initTestCase()
    PASS   : tst_QQuickButton::Material::text()
    PASS   : tst_QQuickButton::Material::cleanupTestCase()
    PASS   : tst_QQuickButton::Universal::initTestCase()
    PASS   : tst_QQuickButton::Universal::text()
    PASS   : tst_QQuickButton::Universal::cleanupTestCase()
    Totals: 9 passed, 0 failed, 0 skipped, 0 blacklisted, 2215ms
    ********* Finished testing of tst_QQuickButton *********

Notice that QTest::qExec() cannot be called multiple times, because
it would print the headers/footers/results separately for each round.

Change-Id: Ibb24b694491d4e790db32e40837c3a5c6d9d2840
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
J-P Nurmi 2016-10-25 09:09:18 +02:00 committed by Liang Qi
parent 7323cd8dc2
commit 3ee6d8d336
2 changed files with 63 additions and 30 deletions

View File

@ -275,6 +275,11 @@ namespace QTest
static QObject *currentTestObject = 0; static QObject *currentTestObject = 0;
static QString mainSourcePath; static QString mainSourcePath;
#if defined(Q_OS_MACOS)
bool macNeedsActivate = false;
IOPMAssertionID powerID;
#endif
class TestMethods { class TestMethods {
Q_DISABLE_COPY(TestMethods) Q_DISABLE_COPY(TestMethods)
public: public:
@ -1357,9 +1362,7 @@ void TestMethods::invokeTests(QObject *testObject) const
{ {
const QMetaObject *metaObject = testObject->metaObject(); const QMetaObject *metaObject = testObject->metaObject();
QTEST_ASSERT(metaObject); QTEST_ASSERT(metaObject);
QTestLog::startLogging();
QTestResult::setCurrentTestFunction("initTestCase"); QTestResult::setCurrentTestFunction("initTestCase");
QTestTable::globalTestTable();
if (m_initTestCaseDataMethod.isValid()) if (m_initTestCaseDataMethod.isValid())
m_initTestCaseDataMethod.invoke(testObject, Qt::DirectConnection); m_initTestCaseDataMethod.invoke(testObject, Qt::DirectConnection);
@ -1404,9 +1407,6 @@ void TestMethods::invokeTests(QObject *testObject) const
} }
QTestResult::finishedCurrentTestFunction(); QTestResult::finishedCurrentTestFunction();
QTestResult::setCurrentTestFunction(0); QTestResult::setCurrentTestFunction(0);
QTestTable::clearGlobalTestTable();
QTestLog::stopLogging();
} }
#if defined(Q_OS_UNIX) #if defined(Q_OS_UNIX)
@ -1710,24 +1710,25 @@ static void initEnvironment()
int QTest::qExec(QObject *testObject, int argc, char **argv) int QTest::qExec(QObject *testObject, int argc, char **argv)
{ {
initEnvironment(); qInit(testObject, argc, argv);
QBenchmarkGlobalData benchmarkData; int ret = qRun();
QBenchmarkGlobalData::current = &benchmarkData; qCleanup();
return ret;
}
#ifdef QTESTLIB_USE_VALGRIND /*! \internal
int callgrindChildExitCode = 0; */
#endif void QTest::qInit(QObject *testObject, int argc, char **argv)
{
initEnvironment();
QBenchmarkGlobalData::current = new QBenchmarkGlobalData;
#if defined(Q_OS_MACX) #if defined(Q_OS_MACX)
bool macNeedsActivate = qApp && (qstrcmp(qApp->metaObject()->className(), "QApplication") == 0); macNeedsActivate = qApp && (qstrcmp(qApp->metaObject()->className(), "QApplication") == 0);
IOPMAssertionID powerID;
// Don't restore saved window state for auto tests. // Don't restore saved window state for auto tests.
QTestPrivate::disableWindowRestore(); QTestPrivate::disableWindowRestore();
#endif #endif
#ifndef QT_NO_EXCEPTIONS
try {
#endif
#if defined(Q_OS_MACX) #if defined(Q_OS_MACX)
if (macNeedsActivate) { if (macNeedsActivate) {
@ -1757,6 +1758,24 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
qtest_qParseArgs(argc, argv, false); qtest_qParseArgs(argc, argv, false);
QTestTable::globalTestTable();
QTestLog::startLogging();
}
/*! \internal
*/
int QTest::qRun()
{
QTEST_ASSERT(currentTestObject);
#ifdef QTESTLIB_USE_VALGRIND
int callgrindChildExitCode = 0;
#endif
#ifndef QT_NO_EXCEPTIONS
try {
#endif
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
if (!noCrashHandler) { if (!noCrashHandler) {
# ifndef Q_CC_MINGW # ifndef Q_CC_MINGW
@ -1792,17 +1811,17 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
for (const QString &tf : qAsConst(QTest::testFunctions)) { for (const QString &tf : qAsConst(QTest::testFunctions)) {
const QByteArray tfB = tf.toLatin1(); const QByteArray tfB = tf.toLatin1();
const QByteArray signature = tfB + QByteArrayLiteral("()"); const QByteArray signature = tfB + QByteArrayLiteral("()");
QMetaMethod m = TestMethods::findMethod(testObject, signature.constData()); QMetaMethod m = TestMethods::findMethod(currentTestObject, signature.constData());
if (!m.isValid() || !isValidSlot(m)) { if (!m.isValid() || !isValidSlot(m)) {
fprintf(stderr, "Unknown test function: '%s'. Possible matches:\n", tfB.constData()); fprintf(stderr, "Unknown test function: '%s'. Possible matches:\n", tfB.constData());
qPrintTestSlots(stderr, tfB.constData()); qPrintTestSlots(stderr, tfB.constData());
fprintf(stderr, "\n%s -functions\nlists all available test functions.\n", argv[0]); fprintf(stderr, "\n%s -functions\nlists all available test functions.\n", QTestResult::currentAppName());
exit(1); exit(1);
} }
commandLineMethods.push_back(m); commandLineMethods.push_back(m);
} }
TestMethods test(testObject, commandLineMethods); TestMethods test(currentTestObject, commandLineMethods);
test.invokeTests(testObject); test.invokeTests(currentTestObject);
} }
#ifndef QT_NO_EXCEPTIONS #ifndef QT_NO_EXCEPTIONS
@ -1827,16 +1846,6 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
} }
#endif #endif
currentTestObject = 0;
QSignalDumper::endDump();
#if defined(Q_OS_MACX)
if (macNeedsActivate) {
IOPMAssertionRelease(powerID);
}
#endif
#ifdef QTESTLIB_USE_VALGRIND #ifdef QTESTLIB_USE_VALGRIND
if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess)
return callgrindChildExitCode; return callgrindChildExitCode;
@ -1846,6 +1855,26 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
return qMin(QTestLog::failCount(), 127); return qMin(QTestLog::failCount(), 127);
} }
/*! \internal
*/
void QTest::qCleanup()
{
currentTestObject = 0;
QTestTable::clearGlobalTestTable();
QTestLog::stopLogging();
delete QBenchmarkGlobalData::current;
QBenchmarkGlobalData::current = 0;
QSignalDumper::endDump();
#if defined(Q_OS_MACOS)
if (macNeedsActivate)
IOPMAssertionRelease(powerID);
#endif
}
/*! /*!
\overload \overload
\since 4.4 \since 4.4

View File

@ -281,6 +281,10 @@ namespace QTest
Q_TESTLIB_EXPORT char *toString(const char *); Q_TESTLIB_EXPORT char *toString(const char *);
Q_TESTLIB_EXPORT char *toString(const void *); Q_TESTLIB_EXPORT char *toString(const void *);
Q_TESTLIB_EXPORT void qInit(QObject *testObject, int argc = 0, char **argv = Q_NULLPTR);
Q_TESTLIB_EXPORT int qRun();
Q_TESTLIB_EXPORT void qCleanup();
Q_TESTLIB_EXPORT int qExec(QObject *testObject, int argc = 0, char **argv = Q_NULLPTR); Q_TESTLIB_EXPORT int qExec(QObject *testObject, int argc = 0, char **argv = Q_NULLPTR);
Q_TESTLIB_EXPORT int qExec(QObject *testObject, const QStringList &arguments); Q_TESTLIB_EXPORT int qExec(QObject *testObject, const QStringList &arguments);