forked from qt-creator/qt-creator
Add capability to run gtest related tests
For now this only applies for 'Run All'. To be able to run only selected tests we first have to introduce the check state for gtest related items as well. Change-Id: I196b56b7fe426f846f2be0df7e21458c2733cbd1 Reviewed-by: Niels Weber <niels.weber@theqtcompany.com>
This commit is contained in:
@@ -27,7 +27,7 @@ SOURCES += \
|
|||||||
testsettings.cpp \
|
testsettings.cpp \
|
||||||
testsettingspage.cpp \
|
testsettingspage.cpp \
|
||||||
testnavigationwidget.cpp \
|
testnavigationwidget.cpp \
|
||||||
testxmloutputreader.cpp
|
testoutputreader.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
testtreeview.h \
|
testtreeview.h \
|
||||||
@@ -50,7 +50,7 @@ HEADERS += \
|
|||||||
testsettings.h \
|
testsettings.h \
|
||||||
testsettingspage.h \
|
testsettingspage.h \
|
||||||
testnavigationwidget.h \
|
testnavigationwidget.h \
|
||||||
testxmloutputreader.h \
|
testoutputreader.h \
|
||||||
autotesticons.h
|
autotesticons.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
|
@@ -69,8 +69,8 @@ QtcCommercialPlugin {
|
|||||||
"testtreeview.h",
|
"testtreeview.h",
|
||||||
"testvisitor.cpp",
|
"testvisitor.cpp",
|
||||||
"testvisitor.h",
|
"testvisitor.h",
|
||||||
"testxmloutputreader.cpp",
|
"testoutputreader.cpp",
|
||||||
"testxmloutputreader.h",
|
"testoutputreader.h",
|
||||||
]
|
]
|
||||||
|
|
||||||
Group {
|
Group {
|
||||||
|
@@ -460,6 +460,7 @@ static TestTreeItem *constructTestTreeItem(const QString &fileName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static TestTreeItem *constructGTestTreeItem(const QString &filePath, const QString &caseName,
|
static TestTreeItem *constructGTestTreeItem(const QString &filePath, const QString &caseName,
|
||||||
|
const QString &proFile,
|
||||||
const TestCodeLocationList &testNames)
|
const TestCodeLocationList &testNames)
|
||||||
{
|
{
|
||||||
TestTreeItem *item = new TestTreeItem(caseName, QString(), TestTreeItem::GTestCase);
|
TestTreeItem *item = new TestTreeItem(caseName, QString(), TestTreeItem::GTestCase);
|
||||||
@@ -468,6 +469,7 @@ static TestTreeItem *constructGTestTreeItem(const QString &filePath, const QStri
|
|||||||
locationAndType.m_type);
|
locationAndType.m_type);
|
||||||
treeItemChild->setLine(locationAndType.m_line);
|
treeItemChild->setLine(locationAndType.m_line);
|
||||||
treeItemChild->setColumn(locationAndType.m_column);
|
treeItemChild->setColumn(locationAndType.m_column);
|
||||||
|
treeItemChild->setMainFile(proFile);
|
||||||
item->appendChild(treeItemChild);
|
item->appendChild(treeItemChild);
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
@@ -1030,7 +1032,7 @@ void TestCodeParser::updateGTests(const CPlusPlus::Document::Ptr &doc,
|
|||||||
proFile = ppList.at(0)->projectFile;
|
proFile = ppList.at(0)->projectFile;
|
||||||
|
|
||||||
foreach (const QString &testName, tests.keys()) {
|
foreach (const QString &testName, tests.keys()) {
|
||||||
TestTreeItem *item = constructGTestTreeItem(fileName, testName, tests.value(testName));
|
TestTreeItem *item = constructGTestTreeItem(fileName, testName, proFile, tests.value(testName));
|
||||||
TestInfo info(item->name(), item->getChildNames(), doc->revision(), doc->editorRevision());
|
TestInfo info(item->name(), item->getChildNames(), doc->revision(), doc->editorRevision());
|
||||||
info.setProfile(proFile);
|
info.setProfile(proFile);
|
||||||
foreach (const TestCodeLocationAndType &testSet, tests.value(testName)) {
|
foreach (const TestCodeLocationAndType &testSet, tests.value(testName)) {
|
||||||
|
@@ -42,7 +42,8 @@ TestConfiguration::TestConfiguration(const QString &testClass, const QStringList
|
|||||||
m_testCaseCount(testCaseCount),
|
m_testCaseCount(testCaseCount),
|
||||||
m_unnamedOnly(false),
|
m_unnamedOnly(false),
|
||||||
m_project(0),
|
m_project(0),
|
||||||
m_guessedConfiguration(false)
|
m_guessedConfiguration(false),
|
||||||
|
m_type(Qt)
|
||||||
{
|
{
|
||||||
if (testCases.size() != 0)
|
if (testCases.size() != 0)
|
||||||
m_testCaseCount = testCases.size();
|
m_testCaseCount = testCases.size();
|
||||||
@@ -71,6 +72,21 @@ void basicProjectInformation(Project *project, const QString &mainFilePath, QStr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void basicProjectInformation(Project *project, const QString &proFile, QString *displayName,
|
||||||
|
Project **targetProject)
|
||||||
|
{
|
||||||
|
CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
|
||||||
|
QList<CppTools::ProjectPart::Ptr> projParts = cppMM->projectInfo(project).projectParts();
|
||||||
|
|
||||||
|
foreach (const CppTools::ProjectPart::Ptr &part, projParts) {
|
||||||
|
if (part->projectFile == proFile) {
|
||||||
|
*displayName = part->displayName;
|
||||||
|
*targetProject = part->project;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void extractEnvironmentInformation(LocalApplicationRunConfiguration *localRunConfiguration,
|
void extractEnvironmentInformation(LocalApplicationRunConfiguration *localRunConfiguration,
|
||||||
QString *workDir, Utils::Environment *env)
|
QString *workDir, Utils::Environment *env)
|
||||||
{
|
{
|
||||||
@@ -81,7 +97,7 @@ void extractEnvironmentInformation(LocalApplicationRunConfiguration *localRunCon
|
|||||||
|
|
||||||
void TestConfiguration::completeTestInformation()
|
void TestConfiguration::completeTestInformation()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!m_mainFilePath.isEmpty(), return);
|
QTC_ASSERT(!m_mainFilePath.isEmpty() || !m_proFile.isEmpty(), return);
|
||||||
|
|
||||||
typedef LocalApplicationRunConfiguration LocalRunConfig;
|
typedef LocalApplicationRunConfiguration LocalRunConfig;
|
||||||
|
|
||||||
@@ -92,7 +108,7 @@ void TestConfiguration::completeTestInformation()
|
|||||||
QString targetFile;
|
QString targetFile;
|
||||||
QString targetName;
|
QString targetName;
|
||||||
QString workDir;
|
QString workDir;
|
||||||
QString proFile;
|
QString proFile = m_proFile;
|
||||||
QString displayName;
|
QString displayName;
|
||||||
Project *targetProject = 0;
|
Project *targetProject = 0;
|
||||||
Utils::Environment env;
|
Utils::Environment env;
|
||||||
@@ -100,7 +116,10 @@ void TestConfiguration::completeTestInformation()
|
|||||||
bool guessedRunConfiguration = false;
|
bool guessedRunConfiguration = false;
|
||||||
setProject(0);
|
setProject(0);
|
||||||
|
|
||||||
|
if (m_proFile.isEmpty())
|
||||||
basicProjectInformation(project, m_mainFilePath, &proFile, &displayName, &targetProject);
|
basicProjectInformation(project, m_mainFilePath, &proFile, &displayName, &targetProject);
|
||||||
|
else
|
||||||
|
basicProjectInformation(project, proFile, &displayName, &targetProject);
|
||||||
|
|
||||||
Target *target = project->activeTarget();
|
Target *target = project->activeTarget();
|
||||||
if (!target)
|
if (!target)
|
||||||
@@ -220,5 +239,10 @@ void TestConfiguration::setGuessedConfiguration(bool guessed)
|
|||||||
m_guessedConfiguration = guessed;
|
m_guessedConfiguration = guessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestConfiguration::setTestType(TestType type)
|
||||||
|
{
|
||||||
|
m_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Autotest
|
} // namespace Autotest
|
||||||
|
@@ -37,6 +37,11 @@ class TestConfiguration : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
enum TestType {
|
||||||
|
Qt,
|
||||||
|
GTest
|
||||||
|
};
|
||||||
|
|
||||||
explicit TestConfiguration(const QString &testClass, const QStringList &testCases,
|
explicit TestConfiguration(const QString &testClass, const QStringList &testCases,
|
||||||
int testCaseCount = 0, QObject *parent = 0);
|
int testCaseCount = 0, QObject *parent = 0);
|
||||||
~TestConfiguration();
|
~TestConfiguration();
|
||||||
@@ -55,6 +60,7 @@ public:
|
|||||||
void setProject(ProjectExplorer::Project *project);
|
void setProject(ProjectExplorer::Project *project);
|
||||||
void setUnnamedOnly(bool unnamedOnly);
|
void setUnnamedOnly(bool unnamedOnly);
|
||||||
void setGuessedConfiguration(bool guessed);
|
void setGuessedConfiguration(bool guessed);
|
||||||
|
void setTestType(TestType type);
|
||||||
|
|
||||||
QString testClass() const { return m_testClass; }
|
QString testClass() const { return m_testClass; }
|
||||||
QStringList testCases() const { return m_testCases; }
|
QStringList testCases() const { return m_testCases; }
|
||||||
@@ -68,6 +74,7 @@ public:
|
|||||||
ProjectExplorer::Project *project() const { return m_project; }
|
ProjectExplorer::Project *project() const { return m_project; }
|
||||||
bool unnamedOnly() const { return m_unnamedOnly; }
|
bool unnamedOnly() const { return m_unnamedOnly; }
|
||||||
bool guessedConfiguration() const { return m_guessedConfiguration; }
|
bool guessedConfiguration() const { return m_guessedConfiguration; }
|
||||||
|
TestType testType() const { return m_type; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_testClass;
|
QString m_testClass;
|
||||||
@@ -83,6 +90,7 @@ private:
|
|||||||
Utils::Environment m_environment;
|
Utils::Environment m_environment;
|
||||||
ProjectExplorer::Project *m_project;
|
ProjectExplorer::Project *m_project;
|
||||||
bool m_guessedConfiguration;
|
bool m_guessedConfiguration;
|
||||||
|
TestType m_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "testxmloutputreader.h"
|
#include "testoutputreader.h"
|
||||||
#include "testresult.h"
|
#include "testresult.h"
|
||||||
|
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QXmlStreamReader>
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -130,11 +131,10 @@ static QString constructBenchmarkInformation(const QString &metric, double value
|
|||||||
.arg(iterations);
|
.arg(iterations);
|
||||||
}
|
}
|
||||||
|
|
||||||
TestXmlOutputReader::TestXmlOutputReader(QProcess *testApplication)
|
TestOutputReader::TestOutputReader(QProcess *testApplication, OutputType type)
|
||||||
:m_testApplication(testApplication)
|
: m_testApplication(testApplication)
|
||||||
|
, m_type(type)
|
||||||
{
|
{
|
||||||
connect(m_testApplication, &QProcess::readyReadStandardOutput,
|
|
||||||
this, &TestXmlOutputReader::processOutput);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CDATAMode {
|
enum CDATAMode {
|
||||||
@@ -146,7 +146,7 @@ enum CDATAMode {
|
|||||||
QTestVersion
|
QTestVersion
|
||||||
};
|
};
|
||||||
|
|
||||||
void TestXmlOutputReader::processOutput()
|
void TestOutputReader::processOutput()
|
||||||
{
|
{
|
||||||
if (!m_testApplication || m_testApplication->state() != QProcess::Running)
|
if (!m_testApplication || m_testApplication->state() != QProcess::Running)
|
||||||
return;
|
return;
|
||||||
@@ -306,5 +306,110 @@ void TestXmlOutputReader::processOutput()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestOutputReader::processGTestOutput()
|
||||||
|
{
|
||||||
|
if (!m_testApplication || m_testApplication->state() != QProcess::Running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static QRegExp newTestStarts(QStringLiteral("^\\[-{10}\\] \\d+ tests? from (.*)$"));
|
||||||
|
static QRegExp testEnds(QStringLiteral("^\\[-{10}\\] \\d+ tests? from (.*) \\((.*)\\)$"));
|
||||||
|
static QRegExp newTestSetStarts(QStringLiteral("^\\[ RUN \\] (.*)$"));
|
||||||
|
static QRegExp testSetSuccess(QStringLiteral("^\\[ OK \\] (.*) \\((.*)\\)$"));
|
||||||
|
static QRegExp testSetFail(QStringLiteral("^\\\[ FAILED \\] (.*) \\((.*)\\)$"));
|
||||||
|
static QRegExp disabledTests(QStringLiteral("^ YOU HAVE (\\d+) DISABLED TESTS?$"));
|
||||||
|
|
||||||
|
static QString currentTestName;
|
||||||
|
static QString currentTestSet;
|
||||||
|
static QString description;
|
||||||
|
static QByteArray unprocessed;
|
||||||
|
|
||||||
|
while (m_testApplication->canReadLine())
|
||||||
|
unprocessed.append(m_testApplication->readLine());
|
||||||
|
|
||||||
|
int lineBreak;
|
||||||
|
while ((lineBreak = unprocessed.indexOf('\n')) != -1) {
|
||||||
|
const QString line = QLatin1String(unprocessed.left(lineBreak));
|
||||||
|
unprocessed.remove(0, lineBreak + 1);
|
||||||
|
if (line.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!line.startsWith(QLatin1Char('['))) {
|
||||||
|
description.append(line).append(QLatin1Char('\n'));
|
||||||
|
if (line.startsWith(QStringLiteral("Note:"))) {
|
||||||
|
auto testResult = new TestResult();
|
||||||
|
testResult->setResult(Result::MessageInternal);
|
||||||
|
testResult->setDescription(line);
|
||||||
|
testResultCreated(testResult);
|
||||||
|
description.clear();
|
||||||
|
} else if (disabledTests.exactMatch(line)) {
|
||||||
|
auto testResult = new TestResult();
|
||||||
|
testResult->setResult(Result::MessageInternal);
|
||||||
|
int disabled = disabledTests.cap(1).toInt();
|
||||||
|
testResult->setDescription(tr("You have %n disabled test(s).", 0, disabled));
|
||||||
|
testResultCreated(testResult);
|
||||||
|
description.clear();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (testEnds.exactMatch(line)) {
|
||||||
|
auto testResult = new TestResult(currentTestName);
|
||||||
|
testResult->setTestCase(currentTestSet);
|
||||||
|
testResult->setResult(Result::MessageTestCaseEnd);
|
||||||
|
testResult->setDescription(tr("Test execution took %1").arg(testEnds.cap(2)));
|
||||||
|
testResultCreated(testResult);
|
||||||
|
currentTestName.clear();
|
||||||
|
currentTestSet.clear();
|
||||||
|
} else if (newTestStarts.exactMatch(line)) {
|
||||||
|
currentTestName = newTestStarts.cap(1);
|
||||||
|
auto testResult = new TestResult(currentTestName);
|
||||||
|
testResult->setResult(Result::MessageTestCaseStart);
|
||||||
|
testResult->setDescription(tr("Executing test case %1").arg(currentTestName));
|
||||||
|
testResultCreated(testResult);
|
||||||
|
} else if (newTestSetStarts.exactMatch(line)) {
|
||||||
|
currentTestSet = newTestSetStarts.cap(1);
|
||||||
|
auto testResult = new TestResult();
|
||||||
|
testResult->setResult(Result::MessageCurrentTest);
|
||||||
|
testResult->setDescription(tr("Entering test set %1").arg(currentTestSet));
|
||||||
|
testResultCreated(testResult);
|
||||||
|
} else if (testSetSuccess.exactMatch(line)) {
|
||||||
|
auto testResult = new TestResult(currentTestName);
|
||||||
|
testResult->setTestCase(currentTestSet);
|
||||||
|
testResult->setResult(Result::Pass);
|
||||||
|
testResultCreated(testResult);
|
||||||
|
testResult = new TestResult(currentTestName);
|
||||||
|
testResult->setTestCase(currentTestSet);
|
||||||
|
testResult->setResult(Result::MessageInternal);
|
||||||
|
testResult->setDescription(tr("Execution took %1.").arg(testSetSuccess.cap(2)));
|
||||||
|
testResultCreated(testResult);
|
||||||
|
emit increaseProgress();
|
||||||
|
} else if (testSetFail.exactMatch(line)) {
|
||||||
|
auto testResult = new TestResult(currentTestName);
|
||||||
|
testResult->setTestCase(currentTestSet);
|
||||||
|
testResult->setResult(Result::Fail);
|
||||||
|
description.chop(1);
|
||||||
|
testResult->setDescription(description);
|
||||||
|
int firstColon = description.indexOf(QLatin1Char(':'));
|
||||||
|
if (firstColon != -1) {
|
||||||
|
int secondColon = description.indexOf(QLatin1Char(':'), firstColon + 1);
|
||||||
|
QString file = constructSourceFilePath(m_testApplication->workingDirectory(),
|
||||||
|
description.left(firstColon),
|
||||||
|
m_testApplication->program());
|
||||||
|
QString line = description.mid(firstColon + 1, secondColon - firstColon - 1);
|
||||||
|
testResult->setFileName(file);
|
||||||
|
testResult->setLine(line.toInt());
|
||||||
|
}
|
||||||
|
testResultCreated(testResult);
|
||||||
|
description.clear();
|
||||||
|
testResult = new TestResult(currentTestName);
|
||||||
|
testResult->setTestCase(currentTestSet);
|
||||||
|
testResult->setResult(Result::MessageInternal);
|
||||||
|
testResult->setDescription(tr("Execution took %1.").arg(testSetFail.cap(2)));
|
||||||
|
testResultCreated(testResult);
|
||||||
|
emit increaseProgress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Autotest
|
} // namespace Autotest
|
@@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QXmlStreamReader>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QProcess;
|
class QProcess;
|
||||||
@@ -33,14 +32,20 @@ QT_END_NAMESPACE
|
|||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class TestXmlOutputReader : public QObject
|
class TestOutputReader : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
TestXmlOutputReader(QProcess *testApplication);
|
enum OutputType {
|
||||||
|
Qt,
|
||||||
|
GTest
|
||||||
|
};
|
||||||
|
|
||||||
|
TestOutputReader(QProcess *testApplication, OutputType type = Qt);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void processOutput();
|
void processOutput();
|
||||||
|
void processGTestOutput();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void testResultCreated(TestResult *testResult);
|
void testResultCreated(TestResult *testResult);
|
||||||
@@ -48,9 +53,10 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QProcess *m_testApplication; // not owned
|
QProcess *m_testApplication; // not owned
|
||||||
|
OutputType m_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Autotest
|
} // namespace Autotest
|
||||||
|
|
||||||
#endif // TESTXMLOUTPUTREADER_H
|
#endif // TESTOUTPUTREADER_H
|
@@ -160,6 +160,7 @@ void TestResultModel::addTestResult(TestResult *testResult, bool autoExpand)
|
|||||||
|
|
||||||
TestResultItem *newItem = new TestResultItem(testResult);
|
TestResultItem *newItem = new TestResultItem(testResult);
|
||||||
// FIXME this might be totally wrong... we need some more unique information!
|
// FIXME this might be totally wrong... we need some more unique information!
|
||||||
|
if (!testResult->className().isEmpty()) {
|
||||||
for (int row = lastRow; row >= 0; --row) {
|
for (int row = lastRow; row >= 0; --row) {
|
||||||
TestResultItem *current = static_cast<TestResultItem *>(topLevelItems.at(row));
|
TestResultItem *current = static_cast<TestResultItem *>(topLevelItems.at(row));
|
||||||
const TestResult *result = current->testResult();
|
const TestResult *result = current->testResult();
|
||||||
@@ -174,6 +175,7 @@ void TestResultModel::addTestResult(TestResult *testResult, bool autoExpand)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// if we have a MessageCurrentTest present, add the new top level item before it
|
// if we have a MessageCurrentTest present, add the new top level item before it
|
||||||
if (lastRow >= 0) {
|
if (lastRow >= 0) {
|
||||||
TestResultItem *current = static_cast<TestResultItem *>(topLevelItems.at(lastRow));
|
TestResultItem *current = static_cast<TestResultItem *>(topLevelItems.at(lastRow));
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
#include "autotestplugin.h"
|
#include "autotestplugin.h"
|
||||||
#include "testresultspane.h"
|
#include "testresultspane.h"
|
||||||
#include "testsettings.h"
|
#include "testsettings.h"
|
||||||
#include "testxmloutputreader.h"
|
#include "testoutputreader.h"
|
||||||
|
|
||||||
#include <coreplugin/progressmanager/futureprogress.h>
|
#include <coreplugin/progressmanager/futureprogress.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
#include <QFutureInterface>
|
#include <QFutureInterface>
|
||||||
|
#include <QMetaObject>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
@@ -109,10 +110,14 @@ void performTestRun(QFutureInterface<void> &futureInterface,
|
|||||||
const QString metricsOption, TestRunner* testRunner)
|
const QString metricsOption, TestRunner* testRunner)
|
||||||
{
|
{
|
||||||
int testCaseCount = 0;
|
int testCaseCount = 0;
|
||||||
|
bool hasQtTests = false;
|
||||||
|
bool hasGTests = false;
|
||||||
foreach (TestConfiguration *config, selectedTests) {
|
foreach (TestConfiguration *config, selectedTests) {
|
||||||
config->completeTestInformation();
|
config->completeTestInformation();
|
||||||
if (config->project()) {
|
if (config->project()) {
|
||||||
testCaseCount += config->testCaseCount();
|
testCaseCount += config->testCaseCount();
|
||||||
|
hasQtTests |= config->testType() == TestConfiguration::Qt;
|
||||||
|
hasGTests |= config->testType() == TestConfiguration::GTest;
|
||||||
} else {
|
} else {
|
||||||
emitTestResultCreated(new FaultyTestResult(Result::MessageWarn,
|
emitTestResultCreated(new FaultyTestResult(Result::MessageWarn,
|
||||||
QObject::tr("Project is null for \"%1\". Removing from test run.\n"
|
QObject::tr("Project is null for \"%1\". Removing from test run.\n"
|
||||||
@@ -127,18 +132,28 @@ void performTestRun(QFutureInterface<void> &futureInterface,
|
|||||||
futureInterface.cancel(); // this kills the process if that is still in the running loop
|
futureInterface.cancel(); // this kills the process if that is still in the running loop
|
||||||
});
|
});
|
||||||
|
|
||||||
TestXmlOutputReader xmlReader(&testProcess);
|
TestOutputReader outputReader(&testProcess);
|
||||||
QObject::connect(&xmlReader, &TestXmlOutputReader::increaseProgress, [&] () {
|
QObject::connect(&outputReader, &TestOutputReader::increaseProgress, [&] () {
|
||||||
futureInterface.setProgressValue(futureInterface.progressValue() + 1);
|
futureInterface.setProgressValue(futureInterface.progressValue() + 1);
|
||||||
});
|
});
|
||||||
QObject::connect(&xmlReader, &TestXmlOutputReader::testResultCreated, &emitTestResultCreated);
|
QObject::connect(&outputReader, &TestOutputReader::testResultCreated, &emitTestResultCreated);
|
||||||
|
|
||||||
QObject::connect(&testProcess, &QProcess::readyRead, &xmlReader, &TestXmlOutputReader::processOutput);
|
|
||||||
|
|
||||||
futureInterface.setProgressRange(0, testCaseCount);
|
futureInterface.setProgressRange(0, testCaseCount);
|
||||||
futureInterface.setProgressValue(0);
|
futureInterface.setProgressValue(0);
|
||||||
|
|
||||||
|
QMetaObject::Connection connection;
|
||||||
foreach (const TestConfiguration *testConfiguration, selectedTests) {
|
foreach (const TestConfiguration *testConfiguration, selectedTests) {
|
||||||
|
if (connection)
|
||||||
|
QObject::disconnect(connection);
|
||||||
|
|
||||||
|
TestConfiguration::TestType testType = testConfiguration->testType();
|
||||||
|
if (testType == TestConfiguration::Qt) {
|
||||||
|
connection = QObject::connect(&testProcess, &QProcess::readyRead, &outputReader,
|
||||||
|
&TestOutputReader::processOutput);
|
||||||
|
} else {
|
||||||
|
connection = QObject::connect(&testProcess, &QProcess::readyRead, &outputReader,
|
||||||
|
&TestOutputReader::processGTestOutput);
|
||||||
|
}
|
||||||
if (futureInterface.isCanceled())
|
if (futureInterface.isCanceled())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -155,12 +170,14 @@ void performTestRun(QFutureInterface<void> &futureInterface,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (testType == TestConfiguration::Qt) {
|
||||||
QStringList argumentList(QLatin1String("-xml"));
|
QStringList argumentList(QLatin1String("-xml"));
|
||||||
if (!metricsOption.isEmpty())
|
if (!metricsOption.isEmpty())
|
||||||
argumentList << metricsOption;
|
argumentList << metricsOption;
|
||||||
if (testConfiguration->testCases().count())
|
if (testConfiguration->testCases().count())
|
||||||
argumentList << testConfiguration->testCases();
|
argumentList << testConfiguration->testCases();
|
||||||
testProcess.setArguments(argumentList);
|
testProcess.setArguments(argumentList);
|
||||||
|
}
|
||||||
|
|
||||||
testProcess.setWorkingDirectory(testConfiguration->workingDirectory());
|
testProcess.setWorkingDirectory(testConfiguration->workingDirectory());
|
||||||
if (Utils::HostOsInfo::isWindowsHost())
|
if (Utils::HostOsInfo::isWindowsHost())
|
||||||
|
@@ -86,7 +86,7 @@ private:
|
|||||||
Type m_type;
|
Type m_type;
|
||||||
unsigned m_line;
|
unsigned m_line;
|
||||||
unsigned m_column;
|
unsigned m_column;
|
||||||
QString m_mainFile;
|
QString m_mainFile; // main for Quick tests, project file for gtest
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TestCodeLocationAndType {
|
struct TestCodeLocationAndType {
|
||||||
|
@@ -236,6 +236,27 @@ QList<TestConfiguration *> TestTreeModel::getAllTestCases() const
|
|||||||
result << tc;
|
result << tc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foundMains.clear();
|
||||||
|
|
||||||
|
// get all Google Tests
|
||||||
|
for (int row = 0, count = m_googleTestRootItem->childCount(); row < count; ++row) {
|
||||||
|
const TestTreeItem *child = m_googleTestRootItem->childItem(row);
|
||||||
|
for (int childRow = 0, childCount = child->childCount(); childRow < childCount; ++childRow) {
|
||||||
|
const QString &proFilePath = child->childItem(childRow)->mainFile();
|
||||||
|
foundMains.insert(proFilePath, foundMains.contains(proFilePath)
|
||||||
|
? foundMains.value(proFilePath) + 1 : 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const QString &proFile, foundMains.keys()) {
|
||||||
|
TestConfiguration *tc = new TestConfiguration(QString(), QStringList(),
|
||||||
|
foundMains.value(proFile));
|
||||||
|
tc->setProFile(proFile);
|
||||||
|
tc->setProject(project);
|
||||||
|
tc->setTestType(TestConfiguration::GTest);
|
||||||
|
result << tc;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user