AutoTest: Parse for file paths in Qt test output

Add option to explicitly check for pattern file://path
and file://path:line which can be provided by the
test code to improve the location information of
qDebug() and friends.

Task-number: QTCREATORBUG-30143
Change-Id: I050ab544c0173769995f7c5e97c89b497ded9215
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Stenger
2024-01-08 16:24:14 +01:00
parent 16123997b8
commit 1d7f6451bb
5 changed files with 40 additions and 2 deletions

View File

@@ -44,7 +44,8 @@ QtTestFramework::QtTestFramework()
title(Tr::tr("Benchmark Metrics")),
Column { metrics }
}, br,
quickCheckForDerivedTests, br
quickCheckForDerivedTests, br,
parseMessages, br
}, st };
});
@@ -100,6 +101,15 @@ QtTestFramework::QtTestFramework()
Tr::tr("Search for Qt Quick tests that are derived from TestCase.\nWarning: Enabling this "
"feature significantly increases scan time."));
parseMessages.setSettingsKey("ParseMessages");
parseMessages.setDefaultValue(false);
parseMessages.setLabelText(Tr::tr("Find user-defined locations"));
parseMessages.setToolTip(
Tr::tr("Parse messages for the pattern \"file://filepath:line\", where \":line\" is "
"optional, and use this as location information.\n"
"Warning: If the patterns are used in code, the location information for debug "
"messages and other messages might improve,\n"
"at the risk of some incorrect locations and lower performance."));
readSettings();
maxWarnings.setEnabler(&limitWarnings);

View File

@@ -31,6 +31,7 @@ public:
Utils::BoolAspect limitWarnings{this};
Utils::IntegerAspect maxWarnings{this};
Utils::BoolAspect quickCheckForDerivedTests{this};
Utils::BoolAspect parseMessages{this};
QStringList testNameForSymbolName(const QString &symbolName) const override;

View File

@@ -4,6 +4,7 @@
#include "qttestoutputreader.h"
#include "qttestresult.h"
#include "qttestframework.h"
#include "../autotesttr.h"
#include "../testtreeitem.h"
@@ -17,6 +18,12 @@ using namespace Utils;
namespace Autotest {
namespace Internal {
static QRegularExpression userFileLocation()
{
static const QRegularExpression regex("^.*\\bfile://((?<file>\\S+))(:(?<line>\\d+))\\b.*$",
QRegularExpression::DotMatchesEverythingOption);
return regex;
}
static QString decode(const QString& original)
{
QString result(original);
@@ -110,6 +117,7 @@ QtTestOutputReader::QtTestOutputReader(Process *testApplication,
, m_mode(mode)
, m_testType(type)
{
m_parseMessages = theQtTestFramework().parseMessages();
}
void QtTestOutputReader::processOutputLine(const QByteArray &outputLine)
@@ -277,6 +285,14 @@ void QtTestOutputReader::processXMLOutput(const QByteArray &outputLine)
} else if (currentTag == QStringLiteral("TestCase")) {
sendFinishMessage(false);
} else if (validEndTags.contains(currentTag.toString())) {
if (m_parseMessages && isTestMessage(m_result)) {
const QRegularExpressionMatch match = userFileLocation().match(m_description);
if (match.hasMatch()) {
// we need to handle possible automatic masking done by qDebug()
processLocationOutput(match.captured("file").replace("\\\\", "\\"),
match.captured("line"));
}
}
sendCompleteInformation();
if (currentTag == QStringLiteral("Incident"))
m_dataTag.clear();
@@ -350,6 +366,11 @@ void QtTestOutputReader::processPlainTextOutput(const QByteArray &outputLine)
if (hasMatch(result)) {
processResultOutput(match.captured(1).toLower().trimmed(), match.captured(2));
if (m_parseMessages && isTestMessage(m_result) && hasMatch(userFileLocation())) {
// we need to handle possible automatic masking done by qDebug()
processLocationOutput(match.captured("file").replace("\\\\", "\\"),
match.captured("line"));
}
} else if (hasMatch(locationUnix)) {
processLocationOutput(match.captured("file"), match.captured("line"));
} else if (hasMatch(locationWin)) {
@@ -416,7 +437,7 @@ void QtTestOutputReader::processLocationOutput(const QStringView file, const QSt
{
QTC_ASSERT(!file.isEmpty(), return);
m_file = constructSourceFilePath(m_buildDir, file.toString());
m_lineNumber = line.toInt();
m_lineNumber = m_file.isEmpty() ? 0 : line.toInt();
}
void QtTestOutputReader::processSummaryFinishOutput()

View File

@@ -66,6 +66,7 @@ private:
QXmlStreamReader m_xmlReader;
OutputMode m_mode = XML;
TestType m_testType = TestType::QtTest;
bool m_parseMessages = false;
bool m_expectTag = true;
};

View File

@@ -52,6 +52,11 @@ enum class ResultType {
LAST_TYPE = Invalid
};
static inline bool isTestMessage(const ResultType &result)
{
return result >= ResultType::MessageDebug && result <= ResultType::MessageError;
}
inline auto qHash(const ResultType &result)
{
return QT_PREPEND_NAMESPACE(qHash(int(result)));