testlib: Produce <error> elements on fatal errors in JUnit reporter
Test errors represents unanticipated problems, e.g., an unhandled exception, or a problem with the implementation of the test. Pick-to: 6.2 Change-Id: I87219e7ffdea56862278f005de44526ad97545f0 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>bb10
parent
dfabb5b677
commit
825e4291cd
|
|
@ -219,66 +219,58 @@ void QJUnitTestLogger::leaveTestCase()
|
|||
void QJUnitTestLogger::addIncident(IncidentTypes type, const char *description,
|
||||
const char *file, int line)
|
||||
{
|
||||
const char *typeBuf = nullptr;
|
||||
|
||||
switch (type) {
|
||||
case QAbstractTestLogger::XPass:
|
||||
++failureCounter;
|
||||
typeBuf = "xpass";
|
||||
break;
|
||||
case QAbstractTestLogger::Pass:
|
||||
typeBuf = "pass";
|
||||
break;
|
||||
case QAbstractTestLogger::XFail:
|
||||
typeBuf = "xfail";
|
||||
break;
|
||||
case QAbstractTestLogger::Fail:
|
||||
++failureCounter;
|
||||
typeBuf = "fail";
|
||||
break;
|
||||
case QAbstractTestLogger::BlacklistedPass:
|
||||
typeBuf = "bpass";
|
||||
break;
|
||||
case QAbstractTestLogger::BlacklistedFail:
|
||||
typeBuf = "bfail";
|
||||
break;
|
||||
case QAbstractTestLogger::BlacklistedXPass:
|
||||
typeBuf = "bxpass";
|
||||
break;
|
||||
case QAbstractTestLogger::BlacklistedXFail:
|
||||
typeBuf = "bxfail";
|
||||
break;
|
||||
default:
|
||||
typeBuf = "??????";
|
||||
break;
|
||||
}
|
||||
|
||||
if (type == QAbstractTestLogger::Fail || type == QAbstractTestLogger::XPass) {
|
||||
QTestElement *failureElement = new QTestElement(QTest::LET_Failure);
|
||||
failureElement->addAttribute(QTest::AI_Type, typeBuf);
|
||||
auto failureType = [&]() {
|
||||
switch (type) {
|
||||
case QAbstractTestLogger::Fail: return "fail";
|
||||
case QAbstractTestLogger::XPass: return "xpass";
|
||||
default: Q_UNREACHABLE();
|
||||
}
|
||||
}();
|
||||
|
||||
// Assume the first line is the message, and the remainder are details
|
||||
QString descriptionString = QString::fromUtf8(description);
|
||||
QString message = descriptionString.section(QLatin1Char('\n'), 0, 0);
|
||||
QString details = descriptionString.section(QLatin1Char('\n'), 1);
|
||||
addFailure(QTest::LET_Failure, failureType, QString::fromUtf8(description));
|
||||
} else if (type == QAbstractTestLogger::XFail) {
|
||||
// Since XFAIL does not add a failure to the testlog in JUnit XML we add a
|
||||
// message, so we still have some information about the expected failure.
|
||||
addMessage(QAbstractTestLogger::Info, QString::fromUtf8(description), file, line);
|
||||
}
|
||||
}
|
||||
|
||||
failureElement->addAttribute(QTest::AI_Message, message.toUtf8().constData());
|
||||
|
||||
if (!details.isEmpty()) {
|
||||
auto messageElement = new QTestElement(QTest::LET_Message);
|
||||
messageElement->addAttribute(QTest::AI_Message, details.toUtf8().constData());
|
||||
failureElement->addLogElement(messageElement);
|
||||
void QJUnitTestLogger::addFailure(QTest::LogElementType elementType,
|
||||
const char *failureType, const QString &failureDescription)
|
||||
{
|
||||
if (elementType == QTest::LET_Failure) {
|
||||
// Make sure we're not adding failure when we already have error,
|
||||
// or adding additional failures when we already have a failure.
|
||||
for (auto *childElement = currentTestCase->childElements();
|
||||
childElement; childElement = childElement->nextElement()) {
|
||||
if (childElement->elementType() == QTest::LET_Error ||
|
||||
childElement->elementType() == QTest::LET_Failure)
|
||||
return;
|
||||
}
|
||||
|
||||
currentTestCase->addLogElement(failureElement);
|
||||
}
|
||||
|
||||
/*
|
||||
Since XFAIL does not add a failure to the testlog in junitxml, add a message, so we still
|
||||
have some information about the expected failure.
|
||||
*/
|
||||
if (type == QAbstractTestLogger::XFail) {
|
||||
QJUnitTestLogger::addMessage(QAbstractTestLogger::Info, QString::fromUtf8(description), file, line);
|
||||
QTestElement *failureElement = new QTestElement(elementType);
|
||||
failureElement->addAttribute(QTest::AI_Type, failureType);
|
||||
|
||||
// Assume the first line is the message, and the remainder are details
|
||||
QString message = failureDescription.section(QLatin1Char('\n'), 0, 0);
|
||||
QString details = failureDescription.section(QLatin1Char('\n'), 1);
|
||||
|
||||
failureElement->addAttribute(QTest::AI_Message, message.toUtf8().constData());
|
||||
|
||||
if (!details.isEmpty()) {
|
||||
auto messageElement = new QTestElement(QTest::LET_Message);
|
||||
messageElement->addAttribute(QTest::AI_Message, details.toUtf8().constData());
|
||||
failureElement->addLogElement(messageElement);
|
||||
}
|
||||
|
||||
currentTestCase->addLogElement(failureElement);
|
||||
|
||||
switch (elementType) {
|
||||
case QTest::LET_Failure: ++failureCounter; break;
|
||||
case QTest::LET_Error: ++errorCounter; break;
|
||||
default: Q_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -294,7 +286,6 @@ void QJUnitTestLogger::addMessage(MessageTypes type, const QString &message, con
|
|||
return;
|
||||
}
|
||||
|
||||
auto messageElement = new QTestElement(QTest::LET_Message);
|
||||
auto systemLogElement = systemOutputElement;
|
||||
const char *typeBuf = nullptr;
|
||||
|
||||
|
|
@ -331,6 +322,12 @@ void QJUnitTestLogger::addMessage(MessageTypes type, const QString &message, con
|
|||
break;
|
||||
}
|
||||
|
||||
if (type == QAbstractTestLogger::QFatal) {
|
||||
addFailure(QTest::LET_Error, typeBuf, message);
|
||||
return;
|
||||
}
|
||||
|
||||
auto messageElement = new QTestElement(QTest::LET_Message);
|
||||
messageElement->addAttribute(QTest::AI_Type, typeBuf);
|
||||
messageElement->addAttribute(QTest::AI_Message, message.toUtf8().constData());
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
//
|
||||
|
||||
#include <QtTest/private/qabstracttestlogger_p.h>
|
||||
#include <QtTest/private/qtestelementattribute_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -83,6 +84,9 @@ class QJUnitTestLogger : public QAbstractTestLogger
|
|||
void enterTestCase(const char *name);
|
||||
void leaveTestCase();
|
||||
|
||||
void addFailure(QTest::LogElementType elementType,
|
||||
const char *failureType, const QString &failureDescription);
|
||||
|
||||
QTestElement *currentTestSuite = nullptr;
|
||||
QTestElement *listOfTestcases = nullptr;
|
||||
QTestElement *currentTestCase = nullptr;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<testsuite name="tst_Assert" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="3" failures="1" errors="0" skipped="0" time="@TEST_DURATION@">
|
||||
<testsuite name="tst_Assert" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="3" failures="0" errors="1" skipped="0" time="@TEST_DURATION@">
|
||||
<properties>
|
||||
<property name="QTestVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
<property name="QtVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
|
|
@ -8,11 +8,8 @@
|
|||
<testcase name="initTestCase" classname="tst_Assert" time="@TEST_DURATION@"/>
|
||||
<testcase name="testNumber1" classname="tst_Assert" time="@TEST_DURATION@"/>
|
||||
<testcase name="testNumber2" classname="tst_Assert" time="@TEST_DURATION@">
|
||||
<!-- type="qfatal" message="ASSERT: "false" in file qtbase/tests/auto/testlib/selftests/assert/tst_assert.cpp, line 0" -->
|
||||
<failure type="fail" message="Received a fatal error."/>
|
||||
<error type="qfatal" message="ASSERT: "false" in file qtbase/tests/auto/testlib/selftests/assert/tst_assert.cpp, line 0"/>
|
||||
</testcase>
|
||||
<system-out/>
|
||||
<system-err>
|
||||
<![CDATA[ASSERT: "false" in file qtbase/tests/auto/testlib/selftests/assert/tst_assert.cpp, line 0]]>
|
||||
</system-err>
|
||||
<system-err/>
|
||||
</testsuite>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<testsuite name="tst_FailDataType" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="2" failures="1" errors="0" skipped="0" time="@TEST_DURATION@">
|
||||
<testsuite name="tst_FailDataType" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="2" failures="0" errors="1" skipped="0" time="@TEST_DURATION@">
|
||||
<properties>
|
||||
<property name="QTestVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
<property name="QtVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
|
|
@ -8,13 +8,10 @@
|
|||
<testcase name="initTestCase" classname="tst_FailDataType" time="@TEST_DURATION@"/>
|
||||
<testcase name="value" classname="tst_FailDataType" time="@TEST_DURATION@">
|
||||
<!-- type="qdebug" message="expected data of type 'QString', got 'bool' for element 0 of data with tag 'bool-as-string'" -->
|
||||
<!-- type="qfatal" message="ASSERT: "false" in file qtbase/src/testlib/qtestdata.cpp, line 0" -->
|
||||
<failure type="fail" message="Received a fatal error."/>
|
||||
<error type="qfatal" message="ASSERT: "false" in file qtbase/src/testlib/qtestdata.cpp, line 0"/>
|
||||
</testcase>
|
||||
<system-out>
|
||||
<![CDATA[expected data of type 'QString', got 'bool' for element 0 of data with tag 'bool-as-string']]>
|
||||
</system-out>
|
||||
<system-err>
|
||||
<![CDATA[ASSERT: "false" in file qtbase/src/testlib/qtestdata.cpp, line 0]]>
|
||||
</system-err>
|
||||
<system-err/>
|
||||
</testsuite>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<testsuite name="tst_FailFetchType" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="2" failures="1" errors="0" skipped="0" time="@TEST_DURATION@">
|
||||
<testsuite name="tst_FailFetchType" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="2" failures="0" errors="1" skipped="0" time="@TEST_DURATION@">
|
||||
<properties>
|
||||
<property name="QTestVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
<property name="QtVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
|
|
@ -7,11 +7,8 @@
|
|||
</properties>
|
||||
<testcase name="initTestCase" classname="tst_FailFetchType" time="@TEST_DURATION@"/>
|
||||
<testcase name="fetch(bool)" classname="tst_FailFetchType" time="@TEST_DURATION@">
|
||||
<!-- type="qfatal" message="Requested type 'QString' does not match available type 'bool'." -->
|
||||
<failure type="fail" message="Received a fatal error."/>
|
||||
<error type="qfatal" message="Requested type 'QString' does not match available type 'bool'."/>
|
||||
</testcase>
|
||||
<system-out/>
|
||||
<system-err>
|
||||
<![CDATA[Requested type 'QString' does not match available type 'bool'.]]>
|
||||
</system-err>
|
||||
<system-err/>
|
||||
</testsuite>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<testsuite name="tst_FetchBogus" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="2" failures="1" errors="0" skipped="0" time="@TEST_DURATION@">
|
||||
<testsuite name="tst_FetchBogus" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="2" failures="0" errors="1" skipped="0" time="@TEST_DURATION@">
|
||||
<properties>
|
||||
<property name="QTestVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
<property name="QtVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
|
|
@ -7,11 +7,8 @@
|
|||
</properties>
|
||||
<testcase name="initTestCase" classname="tst_FetchBogus" time="@TEST_DURATION@"/>
|
||||
<testcase name="fetchBogus(foo)" classname="tst_FetchBogus" time="@TEST_DURATION@">
|
||||
<!-- type="qfatal" message="QFETCH: Requested testdata 'bubu' not available, check your _data function." -->
|
||||
<failure type="fail" message="Received a fatal error."/>
|
||||
<error type="qfatal" message="QFETCH: Requested testdata 'bubu' not available, check your _data function."/>
|
||||
</testcase>
|
||||
<system-out/>
|
||||
<system-err>
|
||||
<![CDATA[QFETCH: Requested testdata 'bubu' not available, check your _data function.]]>
|
||||
</system-err>
|
||||
<system-err/>
|
||||
</testsuite>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<testsuite name="tst_Silent" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="7" failures="3" errors="0" skipped="1" time="@TEST_DURATION@">
|
||||
<testsuite name="tst_Silent" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="7" failures="2" errors="1" skipped="1" time="@TEST_DURATION@">
|
||||
<properties>
|
||||
<property name="QTestVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
<property name="QtVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
|
|
@ -26,8 +26,7 @@
|
|||
<!-- type="system" message="This is a critical message that should not appear in silent test output" -->
|
||||
<!-- type="qinfo" message="This is an info message that should not appear in silent test output" -->
|
||||
<!-- type="info" message="This is an internal testlib info message that should not appear in silent test output" -->
|
||||
<!-- type="qfatal" message="This is a fatal error message that should still appear in silent test output" -->
|
||||
<failure type="fail" message="Received a fatal error."/>
|
||||
<error type="qfatal" message="This is a fatal error message that should still appear in silent test output"/>
|
||||
</testcase>
|
||||
<system-out>
|
||||
<![CDATA[This test should XFAIL]]>
|
||||
|
|
@ -39,6 +38,5 @@
|
|||
<system-err>
|
||||
<![CDATA[This is a warning that should not appear in silent test output]]>
|
||||
<![CDATA[This is an internal testlib warning that should not appear in silent test output]]>
|
||||
<![CDATA[This is a fatal error message that should still appear in silent test output]]>
|
||||
</system-err>
|
||||
</testsuite>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<testsuite name="tst_Watchdog" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="2" failures="1" errors="0" skipped="0" time="@TEST_DURATION@">
|
||||
<testsuite name="tst_Watchdog" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="2" failures="0" errors="1" skipped="0" time="@TEST_DURATION@">
|
||||
<properties>
|
||||
<property name="QTestVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
<property name="QtVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
|
|
@ -7,11 +7,8 @@
|
|||
</properties>
|
||||
<testcase name="initTestCase" classname="tst_Watchdog" time="@TEST_DURATION@"/>
|
||||
<testcase name="delay" classname="tst_Watchdog" time="@TEST_DURATION@">
|
||||
<!-- type="qfatal" message="Test function timed out" -->
|
||||
<failure type="fail" message="Received a fatal error."/>
|
||||
<error type="qfatal" message="Test function timed out"/>
|
||||
</testcase>
|
||||
<system-out/>
|
||||
<system-err>
|
||||
<![CDATA[Test function timed out]]>
|
||||
</system-err>
|
||||
<system-err/>
|
||||
</testsuite>
|
||||
|
|
|
|||
Loading…
Reference in New Issue