forked from qt-creator/qt-creator
AutoTest: Add location info to all GTest results
Currently location information are only set for failed gtest results. One can't jump to the location of a successful test by doing a double click on the corresponding entry in the test result pane. Use the TestTreeModel to obtain the location information for successful tests in the GTestOutputReader. Change-Id: I3fad2d0540edb653ff186011cb92db220748b4f5 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
committed by
Christian Stenger
parent
285f054d74
commit
4e4118dd26
@@ -35,7 +35,7 @@ namespace Internal {
|
|||||||
TestOutputReader *GTestConfiguration::outputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *GTestConfiguration::outputReader(const QFutureInterface<TestResultPtr> &fi,
|
||||||
QProcess *app) const
|
QProcess *app) const
|
||||||
{
|
{
|
||||||
return new GTestOutputReader(fi, app, buildDirectory());
|
return new GTestOutputReader(fi, app, buildDirectory(), projectFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList GTestConfiguration::argumentsForTestRunner() const
|
QStringList GTestConfiguration::argumentsForTestRunner() const
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include "gtestoutputreader.h"
|
#include "gtestoutputreader.h"
|
||||||
#include "gtestresult.h"
|
#include "gtestresult.h"
|
||||||
|
#include "../testtreemodel.h"
|
||||||
|
#include "../testtreeitem.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
@@ -39,9 +41,11 @@ static QString constructSourceFilePath(const QString &path, const QString &fileP
|
|||||||
}
|
}
|
||||||
|
|
||||||
GTestOutputReader::GTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
GTestOutputReader::GTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
||||||
QProcess *testApplication, const QString &buildDirectory)
|
QProcess *testApplication, const QString &buildDirectory,
|
||||||
|
const QString &projectFile)
|
||||||
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
||||||
, m_executable(testApplication ? testApplication->program() : QString())
|
, m_executable(testApplication ? testApplication->program() : QString())
|
||||||
|
, m_projectFile(projectFile)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,8 +98,9 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine)
|
|||||||
m_futureInterface.reportResult(TestResultPtr(testResult));
|
m_futureInterface.reportResult(TestResultPtr(testResult));
|
||||||
m_currentTestName.clear();
|
m_currentTestName.clear();
|
||||||
m_currentTestSet.clear();
|
m_currentTestSet.clear();
|
||||||
|
m_normalizedCurrentTestSet.clear();
|
||||||
} else if (newTestStarts.exactMatch(line)) {
|
} else if (newTestStarts.exactMatch(line)) {
|
||||||
m_currentTestName = newTestStarts.cap(1);
|
setCurrentTestName(newTestStarts.cap(1));
|
||||||
TestResultPtr testResult = TestResultPtr(createDefaultResult());
|
TestResultPtr testResult = TestResultPtr(createDefaultResult());
|
||||||
testResult->setResult(Result::MessageTestCaseStart);
|
testResult->setResult(Result::MessageTestCaseStart);
|
||||||
if (m_iteration > 1) {
|
if (m_iteration > 1) {
|
||||||
@@ -106,7 +111,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine)
|
|||||||
}
|
}
|
||||||
m_futureInterface.reportResult(testResult);
|
m_futureInterface.reportResult(testResult);
|
||||||
} else if (newTestSetStarts.exactMatch(line)) {
|
} else if (newTestSetStarts.exactMatch(line)) {
|
||||||
m_currentTestSet = newTestSetStarts.cap(1);
|
setCurrentTestSet(newTestSetStarts.cap(1));
|
||||||
TestResultPtr testResult = TestResultPtr(new GTestResult);
|
TestResultPtr testResult = TestResultPtr(new GTestResult);
|
||||||
testResult->setResult(Result::MessageCurrentTest);
|
testResult->setResult(Result::MessageCurrentTest);
|
||||||
testResult->setDescription(tr("Entering test set %1").arg(m_currentTestSet));
|
testResult->setDescription(tr("Entering test set %1").arg(m_currentTestSet));
|
||||||
@@ -155,13 +160,87 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GTestOutputReader::setCurrentTestSet(const QString &testSet)
|
||||||
|
{
|
||||||
|
m_currentTestSet = testSet;
|
||||||
|
m_normalizedCurrentTestSet = normalizeName(testSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GTestOutputReader::setCurrentTestName(const QString &testName)
|
||||||
|
{
|
||||||
|
m_currentTestName = testName;
|
||||||
|
m_normalizedTestName = normalizeTestName(testName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GTestOutputReader::normalizeName(const QString &name) const
|
||||||
|
{
|
||||||
|
static QRegExp parameterIndex("/\\d+");
|
||||||
|
|
||||||
|
QString nameWithoutParameterIndices = name;
|
||||||
|
nameWithoutParameterIndices.remove(parameterIndex);
|
||||||
|
|
||||||
|
return nameWithoutParameterIndices.split('/').last();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GTestOutputReader::normalizeTestName(const QString &testname) const
|
||||||
|
{
|
||||||
|
QString nameWithoutTypeParam = testname.split(',').first();
|
||||||
|
|
||||||
|
return normalizeName(nameWithoutTypeParam);
|
||||||
|
}
|
||||||
|
|
||||||
GTestResult *GTestOutputReader::createDefaultResult() const
|
GTestResult *GTestOutputReader::createDefaultResult() const
|
||||||
{
|
{
|
||||||
GTestResult *result = new GTestResult(m_executable, m_currentTestName);
|
GTestResult *result = new GTestResult(m_executable, m_currentTestName);
|
||||||
result->setTestSetName(m_currentTestSet);
|
result->setTestSetName(m_currentTestSet);
|
||||||
result->setIteration(m_iteration);
|
result->setIteration(m_iteration);
|
||||||
|
|
||||||
|
const TestTreeItem *testItem = findTestTreeItemForCurrentLine();
|
||||||
|
if (testItem && testItem->line()) {
|
||||||
|
result->setFileName(testItem->filePath());
|
||||||
|
result->setLine(static_cast<int>(testItem->line()));
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TestTreeItem *GTestOutputReader::findTestTreeItemForCurrentLine() const
|
||||||
|
{
|
||||||
|
const auto item = TestTreeModel::instance()->findNonRooItem([&](const Utils::TreeItem *item) {
|
||||||
|
const TestTreeItem &treeItem = static_cast<const TestTreeItem &>(*item);
|
||||||
|
return matches(treeItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
return static_cast<const TestTreeItem *>(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GTestOutputReader::matches(const TestTreeItem &treeItem) const
|
||||||
|
{
|
||||||
|
if (treeItem.proFile() != m_projectFile)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_currentTestSet.isEmpty())
|
||||||
|
return matchesTestCase(treeItem);
|
||||||
|
|
||||||
|
return matchesTestFunctionOrSet(treeItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GTestOutputReader::matchesTestFunctionOrSet(const TestTreeItem &treeItem) const
|
||||||
|
{
|
||||||
|
if (treeItem.type() != TestTreeItem::TestFunctionOrSet)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QString testItemTestSet = treeItem.parentItem()->name() + '.' + treeItem.name();
|
||||||
|
return testItemTestSet == m_normalizedCurrentTestSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GTestOutputReader::matchesTestCase(const TestTreeItem &treeItem) const
|
||||||
|
{
|
||||||
|
if (treeItem.type() != TestTreeItem::TestCase)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return treeItem.name() == m_normalizedTestName;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Autotest
|
} // namespace Autotest
|
||||||
|
@@ -33,6 +33,7 @@ namespace Autotest {
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class GTestResult;
|
class GTestResult;
|
||||||
|
class TestTreeItem;
|
||||||
|
|
||||||
class GTestOutputReader : public TestOutputReader
|
class GTestOutputReader : public TestOutputReader
|
||||||
{
|
{
|
||||||
@@ -40,16 +41,29 @@ class GTestOutputReader : public TestOutputReader
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
GTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
GTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
||||||
QProcess *testApplication, const QString &buildDirectory);
|
QProcess *testApplication, const QString &buildDirectory,
|
||||||
|
const QString &projectFile);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void processOutput(const QByteArray &outputLine) override;
|
void processOutput(const QByteArray &outputLine) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void setCurrentTestSet(const QString &testSet);
|
||||||
|
void setCurrentTestName(const QString &testName);
|
||||||
|
QString normalizeName(const QString &name) const;
|
||||||
|
QString normalizeTestName(const QString &testname) const;
|
||||||
GTestResult *createDefaultResult() const;
|
GTestResult *createDefaultResult() const;
|
||||||
|
const TestTreeItem *findTestTreeItemForCurrentLine() const;
|
||||||
|
bool matches(const TestTreeItem &treeItem) const;
|
||||||
|
bool matchesTestFunctionOrSet(const TestTreeItem &treeItem) const;
|
||||||
|
bool matchesTestCase(const TestTreeItem &treeItem) const;
|
||||||
|
|
||||||
QString m_executable;
|
QString m_executable;
|
||||||
|
QString m_projectFile;
|
||||||
QString m_currentTestName;
|
QString m_currentTestName;
|
||||||
|
QString m_normalizedTestName;
|
||||||
QString m_currentTestSet;
|
QString m_currentTestSet;
|
||||||
|
QString m_normalizedCurrentTestSet;
|
||||||
QString m_description;
|
QString m_description;
|
||||||
int m_iteration = 1;
|
int m_iteration = 1;
|
||||||
};
|
};
|
||||||
|
@@ -73,6 +73,7 @@ public:
|
|||||||
QString executableFilePath() const;
|
QString executableFilePath() const;
|
||||||
QString workingDirectory() const;
|
QString workingDirectory() const;
|
||||||
QString buildDirectory() const { return m_buildDir; }
|
QString buildDirectory() const { return m_buildDir; }
|
||||||
|
QString projectFile() const { return m_projectFile; }
|
||||||
QString displayName() const { return m_displayName; }
|
QString displayName() const { return m_displayName; }
|
||||||
Utils::Environment environment() const { return m_environment; }
|
Utils::Environment environment() const { return m_environment; }
|
||||||
ProjectExplorer::Project *project() const { return m_project.data(); }
|
ProjectExplorer::Project *project() const { return m_project.data(); }
|
||||||
|
Reference in New Issue
Block a user