diff --git a/src/testlib/qjunittestlogger.cpp b/src/testlib/qjunittestlogger.cpp index 1e375bb33f..bc384a7af2 100644 --- a/src/testlib/qjunittestlogger.cpp +++ b/src/testlib/qjunittestlogger.cpp @@ -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()); diff --git a/src/testlib/qjunittestlogger_p.h b/src/testlib/qjunittestlogger_p.h index 7998ae8fb7..91d2774144 100644 --- a/src/testlib/qjunittestlogger_p.h +++ b/src/testlib/qjunittestlogger_p.h @@ -52,6 +52,7 @@ // #include +#include 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; diff --git a/tests/auto/testlib/selftests/expected_assert.junitxml b/tests/auto/testlib/selftests/expected_assert.junitxml index 5c854832f2..b000a0decc 100644 --- a/tests/auto/testlib/selftests/expected_assert.junitxml +++ b/tests/auto/testlib/selftests/expected_assert.junitxml @@ -1,5 +1,5 @@ - + @@ -8,11 +8,8 @@ - - + - - - + diff --git a/tests/auto/testlib/selftests/expected_faildatatype.junitxml b/tests/auto/testlib/selftests/expected_faildatatype.junitxml index 3a2c8bf19b..697fe1e759 100644 --- a/tests/auto/testlib/selftests/expected_faildatatype.junitxml +++ b/tests/auto/testlib/selftests/expected_faildatatype.junitxml @@ -1,5 +1,5 @@ - + @@ -8,13 +8,10 @@ - - + - - - + diff --git a/tests/auto/testlib/selftests/expected_failfetchtype.junitxml b/tests/auto/testlib/selftests/expected_failfetchtype.junitxml index 58ad4e725f..f7c0bb72cb 100644 --- a/tests/auto/testlib/selftests/expected_failfetchtype.junitxml +++ b/tests/auto/testlib/selftests/expected_failfetchtype.junitxml @@ -1,5 +1,5 @@ - + @@ -7,11 +7,8 @@ - - + - - - + diff --git a/tests/auto/testlib/selftests/expected_fetchbogus.junitxml b/tests/auto/testlib/selftests/expected_fetchbogus.junitxml index ef9ac181ac..96f8df5fbd 100644 --- a/tests/auto/testlib/selftests/expected_fetchbogus.junitxml +++ b/tests/auto/testlib/selftests/expected_fetchbogus.junitxml @@ -1,5 +1,5 @@ - + @@ -7,11 +7,8 @@ - - + - - - + diff --git a/tests/auto/testlib/selftests/expected_silent.junitxml b/tests/auto/testlib/selftests/expected_silent.junitxml index f1f0c70599..7293e30170 100644 --- a/tests/auto/testlib/selftests/expected_silent.junitxml +++ b/tests/auto/testlib/selftests/expected_silent.junitxml @@ -1,5 +1,5 @@ - + @@ -26,8 +26,7 @@ - - + @@ -39,6 +38,5 @@ - diff --git a/tests/auto/testlib/selftests/expected_watchdog.junitxml b/tests/auto/testlib/selftests/expected_watchdog.junitxml index ba2269ca4e..f9b7e6fd9a 100644 --- a/tests/auto/testlib/selftests/expected_watchdog.junitxml +++ b/tests/auto/testlib/selftests/expected_watchdog.junitxml @@ -1,5 +1,5 @@ - + @@ -7,11 +7,8 @@ - - + - - - +