From 4ba039fefae957667de8cc97e6bc4959377c74ba Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 17 Jul 2024 12:18:50 +0200 Subject: [PATCH] AutoTest: Display duration inside summary if available If the test framework reports durations for the test execution take these into account and display them inside the summary. This will display wrong times when mixing test frameworks with and without displaying durations. Fixes: QTCREATORBUG-31242 Change-Id: I3d01f53ed370cf0ce631c80979d3d505a895dc16 Reviewed-by: David Schulz --- src/plugins/autotest/gtest/gtestoutputreader.cpp | 1 + src/plugins/autotest/qtest/qttestoutputreader.cpp | 5 ++++- src/plugins/autotest/testoutputreader.h | 4 ++++ src/plugins/autotest/testresultmodel.cpp | 5 +++++ src/plugins/autotest/testresultmodel.h | 2 ++ src/plugins/autotest/testresultspane.cpp | 5 ++++- src/plugins/autotest/testrunner.cpp | 2 ++ src/plugins/autotest/testrunner.h | 1 + 8 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/plugins/autotest/gtest/gtestoutputreader.cpp b/src/plugins/autotest/gtest/gtestoutputreader.cpp index 8e4fcd5a766..2584fc9cda7 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.cpp +++ b/src/plugins/autotest/gtest/gtestoutputreader.cpp @@ -71,6 +71,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine) testResult.setResult(ResultType::TestEnd); testResult.setDescription(Tr::tr("Test execution took %1.").arg(match.captured(2))); testResult.setDuration(match.captured(3)); + m_executionDuration = m_executionDuration.value_or(0) + match.captured(3).toInt(); reportResult(testResult); m_currentTestSuite.clear(); m_currentTestCase.clear(); diff --git a/src/plugins/autotest/qtest/qttestoutputreader.cpp b/src/plugins/autotest/qtest/qttestoutputreader.cpp index 9a5eab32996..99693357a05 100644 --- a/src/plugins/autotest/qtest/qttestoutputreader.cpp +++ b/src/plugins/autotest/qtest/qttestoutputreader.cpp @@ -283,6 +283,7 @@ void QtTestOutputReader::processXMLOutput(const QByteArray &outputLine) m_testCase.clear(); } else if (currentTag == QStringLiteral("TestCase")) { sendFinishMessage(false); + m_executionDuration = qRound(m_duration.toDouble()); } else if (validEndTags.contains(currentTag.toString())) { if (m_parseMessages && isTestMessage(m_result)) { const QRegularExpressionMatch match = userFileLocation().match(m_description); @@ -343,7 +344,7 @@ void QtTestOutputReader::processPlainTextOutput(const QByteArray &outputLine) static const QRegularExpression config("^Config: Using QtTest library (.*), " "(Qt (\\d+(\\.\\d+){2}) \\(.*\\))$"); static const QRegularExpression summary("^Totals: (\\d+) passed, (\\d+) failed, " - "(\\d+) skipped(, (\\d+) blacklisted)?(, \\d+ms)?$"); + "(\\d+) skipped(, (\\d+) blacklisted)?(, (\\d+)ms)?$"); static const QRegularExpression finish("^[*]{9} Finished testing of (.*) [*]{9}$"); static const QRegularExpression result("^(PASS |FAIL! |XFAIL |XPASS |SKIP |RESULT " @@ -389,6 +390,8 @@ void QtTestOutputReader::processPlainTextOutput(const QByteArray &outputLine) // BlacklistedXYZ is wrong here, but we use it for convenience (avoids another enum value) if (int blacklisted = match.captured(5).toInt()) m_summary[ResultType::BlacklistedPass] = blacklisted; + if (match.hasCaptured(7)) + m_executionDuration.emplace(match.captured(7).toInt()); processSummaryFinishOutput(); } else if (finish.match(line).hasMatch()) { processSummaryFinishOutput(); diff --git a/src/plugins/autotest/testoutputreader.h b/src/plugins/autotest/testoutputreader.h index 247d036831a..f615f5a2056 100644 --- a/src/plugins/autotest/testoutputreader.h +++ b/src/plugins/autotest/testoutputreader.h @@ -25,6 +25,8 @@ public: int disabledTests() const { return m_disabled; } bool hasSummary() const { return !m_summary.isEmpty(); } QHash summary() const { return m_summary; } + bool hasDuration() const { return m_executionDuration.has_value(); } + int duration() const { return m_executionDuration.value(); } void setId(const QString &id) { m_id = id; } QString id() const { return m_id; } @@ -49,6 +51,8 @@ protected: QString m_id; QHash m_summary; int m_disabled = -1; + std::optional m_executionDuration; + private: enum class SanitizerOutputMode { None, Asan, Ubsan}; TestResult m_sanitizerResult; diff --git a/src/plugins/autotest/testresultmodel.cpp b/src/plugins/autotest/testresultmodel.cpp index 46c6d71b8f4..7a1295a4391 100644 --- a/src/plugins/autotest/testresultmodel.cpp +++ b/src/plugins/autotest/testresultmodel.cpp @@ -238,6 +238,10 @@ TestResultModel::TestResultModel(QObject *parent) this, [this](const QString &id, const QHash &summary){ m_reportedSummary.insert(id, summary); }); + connect(TestRunner::instance(), &TestRunner::reportDuration, + this, [this](int duration){ + m_reportedDurations.emplace(m_reportedDurations.value_or(0) + duration); + }); } void TestResultModel::updateParent(const TestResultItem *item) @@ -354,6 +358,7 @@ void TestResultModel::clearTestResults() clear(); m_testResultCount.clear(); m_reportedSummary.clear(); + m_reportedDurations.reset(); m_disabled = 0; m_fileNames.clear(); m_maxWidthOfFileName = 0; diff --git a/src/plugins/autotest/testresultmodel.h b/src/plugins/autotest/testresultmodel.h index add1f717538..07569bd6809 100644 --- a/src/plugins/autotest/testresultmodel.h +++ b/src/plugins/autotest/testresultmodel.h @@ -70,6 +70,7 @@ public: int resultTypeCount(ResultType type) const; int disabledTests() const { return m_disabled; } + std::optional reportedDuration() const { return m_reportedDurations; } void raiseDisabledTests(int amount) { m_disabled += amount; } private: @@ -80,6 +81,7 @@ private: void updateParent(const TestResultItem *item); QHash> m_testResultCount; QHash> m_reportedSummary; + std::optional m_reportedDurations = std::nullopt; int m_widthOfLineNumber = 0; int m_maxWidthOfFileName = 0; int m_disabled = 0; diff --git a/src/plugins/autotest/testresultspane.cpp b/src/plugins/autotest/testresultspane.cpp index 642eb67cb6a..1ccbd986f0a 100644 --- a/src/plugins/autotest/testresultspane.cpp +++ b/src/plugins/autotest/testresultspane.cpp @@ -500,7 +500,10 @@ void TestResultsPane::updateSummaryLabel() count = m_model->disabledTests(); if (count) labelText += ", " + QString::number(count) + ' ' + Tr::tr("disabled"); - labelText.append(".

"); + if (auto millisec = m_model->reportedDuration()) + labelText += ".   (" + QString::number(*millisec) + " ms)

"; + else + labelText.append(".

"); m_summaryLabel->setText(labelText); } diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 49bbbd4e920..f794e45eef4 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -454,6 +454,8 @@ void TestRunner::runTestsHelper() emit hadDisabledTests(disabled); if (testStorage->m_outputReader->hasSummary()) emit reportSummary(testStorage->m_outputReader->id(), testStorage->m_outputReader->summary()); + if (testStorage->m_outputReader->hasDuration()) + emit reportDuration(testStorage->m_outputReader->duration()); testStorage->m_outputReader->resetCommandlineColor(); } diff --git a/src/plugins/autotest/testrunner.h b/src/plugins/autotest/testrunner.h index 507ada786f6..275b17c7ccc 100644 --- a/src/plugins/autotest/testrunner.h +++ b/src/plugins/autotest/testrunner.h @@ -57,6 +57,7 @@ signals: void testResultReady(const TestResult &result); void hadDisabledTests(int disabled); void reportSummary(const QString &id, const QHash &summary); + void reportDuration(int duration); private: void buildProject(ProjectExplorer::Project *project);