forked from qt-creator/qt-creator
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:
@@ -44,7 +44,8 @@ QtTestFramework::QtTestFramework()
|
|||||||
title(Tr::tr("Benchmark Metrics")),
|
title(Tr::tr("Benchmark Metrics")),
|
||||||
Column { metrics }
|
Column { metrics }
|
||||||
}, br,
|
}, br,
|
||||||
quickCheckForDerivedTests, br
|
quickCheckForDerivedTests, br,
|
||||||
|
parseMessages, br
|
||||||
}, st };
|
}, st };
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -100,6 +101,15 @@ QtTestFramework::QtTestFramework()
|
|||||||
Tr::tr("Search for Qt Quick tests that are derived from TestCase.\nWarning: Enabling this "
|
Tr::tr("Search for Qt Quick tests that are derived from TestCase.\nWarning: Enabling this "
|
||||||
"feature significantly increases scan time."));
|
"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();
|
readSettings();
|
||||||
|
|
||||||
maxWarnings.setEnabler(&limitWarnings);
|
maxWarnings.setEnabler(&limitWarnings);
|
||||||
|
@@ -31,6 +31,7 @@ public:
|
|||||||
Utils::BoolAspect limitWarnings{this};
|
Utils::BoolAspect limitWarnings{this};
|
||||||
Utils::IntegerAspect maxWarnings{this};
|
Utils::IntegerAspect maxWarnings{this};
|
||||||
Utils::BoolAspect quickCheckForDerivedTests{this};
|
Utils::BoolAspect quickCheckForDerivedTests{this};
|
||||||
|
Utils::BoolAspect parseMessages{this};
|
||||||
|
|
||||||
QStringList testNameForSymbolName(const QString &symbolName) const override;
|
QStringList testNameForSymbolName(const QString &symbolName) const override;
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
#include "qttestoutputreader.h"
|
#include "qttestoutputreader.h"
|
||||||
|
|
||||||
#include "qttestresult.h"
|
#include "qttestresult.h"
|
||||||
|
#include "qttestframework.h"
|
||||||
#include "../autotesttr.h"
|
#include "../autotesttr.h"
|
||||||
#include "../testtreeitem.h"
|
#include "../testtreeitem.h"
|
||||||
|
|
||||||
@@ -17,6 +18,12 @@ using namespace Utils;
|
|||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
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)
|
static QString decode(const QString& original)
|
||||||
{
|
{
|
||||||
QString result(original);
|
QString result(original);
|
||||||
@@ -110,6 +117,7 @@ QtTestOutputReader::QtTestOutputReader(Process *testApplication,
|
|||||||
, m_mode(mode)
|
, m_mode(mode)
|
||||||
, m_testType(type)
|
, m_testType(type)
|
||||||
{
|
{
|
||||||
|
m_parseMessages = theQtTestFramework().parseMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
void QtTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
||||||
@@ -277,6 +285,14 @@ void QtTestOutputReader::processXMLOutput(const QByteArray &outputLine)
|
|||||||
} else if (currentTag == QStringLiteral("TestCase")) {
|
} else if (currentTag == QStringLiteral("TestCase")) {
|
||||||
sendFinishMessage(false);
|
sendFinishMessage(false);
|
||||||
} else if (validEndTags.contains(currentTag.toString())) {
|
} 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();
|
sendCompleteInformation();
|
||||||
if (currentTag == QStringLiteral("Incident"))
|
if (currentTag == QStringLiteral("Incident"))
|
||||||
m_dataTag.clear();
|
m_dataTag.clear();
|
||||||
@@ -350,6 +366,11 @@ void QtTestOutputReader::processPlainTextOutput(const QByteArray &outputLine)
|
|||||||
|
|
||||||
if (hasMatch(result)) {
|
if (hasMatch(result)) {
|
||||||
processResultOutput(match.captured(1).toLower().trimmed(), match.captured(2));
|
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)) {
|
} else if (hasMatch(locationUnix)) {
|
||||||
processLocationOutput(match.captured("file"), match.captured("line"));
|
processLocationOutput(match.captured("file"), match.captured("line"));
|
||||||
} else if (hasMatch(locationWin)) {
|
} else if (hasMatch(locationWin)) {
|
||||||
@@ -416,7 +437,7 @@ void QtTestOutputReader::processLocationOutput(const QStringView file, const QSt
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(!file.isEmpty(), return);
|
QTC_ASSERT(!file.isEmpty(), return);
|
||||||
m_file = constructSourceFilePath(m_buildDir, file.toString());
|
m_file = constructSourceFilePath(m_buildDir, file.toString());
|
||||||
m_lineNumber = line.toInt();
|
m_lineNumber = m_file.isEmpty() ? 0 : line.toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtTestOutputReader::processSummaryFinishOutput()
|
void QtTestOutputReader::processSummaryFinishOutput()
|
||||||
|
@@ -66,6 +66,7 @@ private:
|
|||||||
QXmlStreamReader m_xmlReader;
|
QXmlStreamReader m_xmlReader;
|
||||||
OutputMode m_mode = XML;
|
OutputMode m_mode = XML;
|
||||||
TestType m_testType = TestType::QtTest;
|
TestType m_testType = TestType::QtTest;
|
||||||
|
bool m_parseMessages = false;
|
||||||
bool m_expectTag = true;
|
bool m_expectTag = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -52,6 +52,11 @@ enum class ResultType {
|
|||||||
LAST_TYPE = Invalid
|
LAST_TYPE = Invalid
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline bool isTestMessage(const ResultType &result)
|
||||||
|
{
|
||||||
|
return result >= ResultType::MessageDebug && result <= ResultType::MessageError;
|
||||||
|
}
|
||||||
|
|
||||||
inline auto qHash(const ResultType &result)
|
inline auto qHash(const ResultType &result)
|
||||||
{
|
{
|
||||||
return QT_PREPEND_NAMESPACE(qHash(int(result)));
|
return QT_PREPEND_NAMESPACE(qHash(int(result)));
|
||||||
|
Reference in New Issue
Block a user