diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2021-09-07 15:30:34 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2022-01-13 19:47:22 +0100 |
commit | 13d2e13290d61fbe85c0744b6dc4115c07d4a1fa (patch) | |
tree | def4ec6f2090046b78eb76b2fc34ea87242b97e6 /src/testlib/qtestcase.cpp | |
parent | 95e49966889069ffafca0167d7766cbc40fda8eb (diff) |
Make counts of various types of test result add up correctly
Added tests for repeated skips and failures (from within void lambdas,
to simulate skips and failures from within event handlers). These
exhibit yet more ways to count more than one outcome for a test. The
new QTest::failOnWarning() can also provoke more than one failure from
a single test, and several existing selftests exhibited various ways
for the Totals line's counts to add up to more than the number of
actual tests run.
Fixed counting so that only the first decisive incident is counted.
Tests can still report later failure or skipping, but only the first
is counted.
Added a currentTestState in qtestlog.cpp, by which it keeps track of
whether the test has resolved to a result, and clearCurrentTestState()
by which other code can reset that at the end of each test. This
brought to light various places where test-end clean-up was not being
handled - due to failure or skipping in a *_data() method or init, or
a skip in cleanup.
Fixes: QTBUG-95661
Change-Id: I5d24a37a53d3db225fa602649d8aad8f5ed6c1ad
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/testlib/qtestcase.cpp')
-rw-r--r-- | src/testlib/qtestcase.cpp | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 9a93c41b5c..673605307f 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -946,33 +946,38 @@ void TestMethods::invokeTestOnData(int index) const do { if (m_initMethod.isValid()) m_initMethod.invoke(QTest::currentTestObject, Qt::DirectConnection); - if (QTestResult::skipCurrentTest() || QTestResult::currentTestFailed()) - break; - QBenchmarkTestMethodData::current->result = QBenchmarkResult(); - QBenchmarkTestMethodData::current->resultAccepted = false; + const bool initQuit = + QTestResult::skipCurrentTest() || QTestResult::currentTestFailed(); + if (!initQuit) { + QBenchmarkTestMethodData::current->result = QBenchmarkResult(); + QBenchmarkTestMethodData::current->resultAccepted = false; - QBenchmarkGlobalData::current->context.tag = - QLatin1String( - QTestResult::currentDataTag() - ? QTestResult::currentDataTag() : ""); + QBenchmarkGlobalData::current->context.tag = QLatin1String( + QTestResult::currentDataTag() ? QTestResult::currentDataTag() : ""); - invokeOk = m_methods[index].invoke(QTest::currentTestObject, Qt::DirectConnection); - if (!invokeOk) - QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__); + invokeOk = m_methods[index].invoke(QTest::currentTestObject, Qt::DirectConnection); + if (!invokeOk) + QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__); - isBenchmark = QBenchmarkTestMethodData::current->isBenchmark(); + isBenchmark = QBenchmarkTestMethodData::current->isBenchmark(); + } else { + invokeOk = false; + } QTestResult::finishedCurrentTestData(); - if (m_cleanupMethod.isValid()) - m_cleanupMethod.invoke(QTest::currentTestObject, Qt::DirectConnection); + if (!initQuit) { + if (m_cleanupMethod.isValid()) + m_cleanupMethod.invoke(QTest::currentTestObject, Qt::DirectConnection); - // Process any deleteLater(), like event-loop based apps would do. Fixes memleak reports. - if (QCoreApplication::instance()) - QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); - - // If the test isn't a benchmark, finalize the result after cleanup() has finished. + // Process any deleteLater(), used by event-loop-based apps. + // Fixes memleak reports. + if (QCoreApplication::instance()) + QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); + } + // If the test isn't a benchmark, finalize the result after + // cleanup() has finished (or init has lead us to skip the test). if (!isBenchmark) QTestResult::finishedCurrentTestDataCleanup(); @@ -1522,7 +1527,7 @@ void TestMethods::invokeTests(QObject *testObject) const QSignalDumper::startDump(); - if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) { + if (!QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed()) { if (m_initTestCaseMethod.isValid()) m_initTestCaseMethod.invoke(testObject, Qt::DirectConnection); @@ -1544,12 +1549,15 @@ void TestMethods::invokeTests(QObject *testObject) const } } + const bool wasSkipped = QTestResult::skipCurrentTest(); QTestResult::setSkipCurrentTest(false); QTestResult::setBlacklistCurrentTest(false); QTestResult::setCurrentTestFunction("cleanupTestCase"); if (m_cleanupTestCaseMethod.isValid()) m_cleanupTestCaseMethod.invoke(testObject, Qt::DirectConnection); QTestResult::finishedCurrentTestData(); + // Restore skip state as it affects decision on whether we passed: + QTestResult::setSkipCurrentTest(wasSkipped || QTestResult::skipCurrentTest()); QTestResult::finishedCurrentTestDataCleanup(); } QTestResult::finishedCurrentTestFunction(); |