forked from qt-creator/qt-creator
AutoTest: Fix appending test results with the same name
If two test cases had the same name but came from a different executable the results pane still might have shown any later one (badly) cascaded inside the first one. Avoid this by providing an additional unique information (the respective executable for the test case) Task-number: QTCREATORBUG-18502 Change-Id: Ib071e389758b6269a9a90cc4c4afbcf86ca583ac Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -41,6 +41,7 @@ static QString constructSourceFilePath(const QString &path, const QString &fileP
|
||||
GTestOutputReader::GTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
||||
QProcess *testApplication, const QString &buildDirectory)
|
||||
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
||||
, m_executable(testApplication ? testApplication->program() : QString())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -75,7 +76,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine)
|
||||
m_futureInterface.reportResult(testResult);
|
||||
m_description.clear();
|
||||
} else if (disabledTests.exactMatch(line)) {
|
||||
TestResultPtr testResult = TestResultPtr(new GTestResult());
|
||||
TestResultPtr testResult = TestResultPtr(new GTestResult);
|
||||
testResult->setResult(Result::MessageDisabledTests);
|
||||
int disabled = disabledTests.cap(1).toInt();
|
||||
testResult->setDescription(tr("You have %n disabled test(s).", 0, disabled));
|
||||
@@ -106,7 +107,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine)
|
||||
m_futureInterface.reportResult(testResult);
|
||||
} else if (newTestSetStarts.exactMatch(line)) {
|
||||
m_currentTestSet = newTestSetStarts.cap(1);
|
||||
TestResultPtr testResult = TestResultPtr(new GTestResult());
|
||||
TestResultPtr testResult = TestResultPtr(new GTestResult);
|
||||
testResult->setResult(Result::MessageCurrentTest);
|
||||
testResult->setDescription(tr("Entering test set %1").arg(m_currentTestSet));
|
||||
m_futureInterface.reportResult(testResult);
|
||||
@@ -156,7 +157,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine)
|
||||
|
||||
GTestResult *GTestOutputReader::createDefaultResult() const
|
||||
{
|
||||
GTestResult *result = new GTestResult(m_currentTestName);
|
||||
GTestResult *result = new GTestResult(m_executable, m_currentTestName);
|
||||
result->setTestSetName(m_currentTestSet);
|
||||
result->setIteration(m_iteration);
|
||||
return result;
|
||||
|
@@ -47,6 +47,7 @@ protected:
|
||||
|
||||
private:
|
||||
GTestResult *createDefaultResult() const;
|
||||
QString m_executable;
|
||||
QString m_currentTestName;
|
||||
QString m_currentTestSet;
|
||||
QString m_description;
|
||||
|
@@ -33,6 +33,11 @@ GTestResult::GTestResult(const QString &name)
|
||||
{
|
||||
}
|
||||
|
||||
GTestResult::GTestResult(const QString &executable, const QString &name)
|
||||
: TestResult(executable, name)
|
||||
{
|
||||
}
|
||||
|
||||
const QString GTestResult::outputString(bool selected) const
|
||||
{
|
||||
const QString &desc = description();
|
||||
|
@@ -34,6 +34,7 @@ class GTestResult : public TestResult
|
||||
{
|
||||
public:
|
||||
explicit GTestResult(const QString &name = QString());
|
||||
GTestResult(const QString &executable, const QString &name);
|
||||
const QString outputString(bool selected) const override;
|
||||
|
||||
void setTestSetName(const QString &testSetName) { m_testSetName = testSetName; }
|
||||
|
@@ -132,6 +132,7 @@ QtTestOutputReader::QtTestOutputReader(const QFutureInterface<TestResultPtr> &fu
|
||||
QProcess *testApplication, const QString &buildDirectory,
|
||||
OutputMode mode)
|
||||
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
||||
, m_executable(testApplication ? testApplication->program() : QString())
|
||||
, m_mode(mode)
|
||||
{
|
||||
}
|
||||
@@ -419,7 +420,7 @@ void QtTestOutputReader::processSummaryFinishOutput()
|
||||
|
||||
QtTestResult *QtTestOutputReader::createDefaultResult() const
|
||||
{
|
||||
QtTestResult *result = new QtTestResult(m_className);
|
||||
QtTestResult *result = new QtTestResult(m_executable, m_className);
|
||||
result->setFunctionName(m_testCase);
|
||||
result->setDataTag(m_dataTag);
|
||||
return result;
|
||||
|
@@ -78,6 +78,7 @@ private:
|
||||
};
|
||||
|
||||
CDATAMode m_cdataMode = None;
|
||||
QString m_executable;
|
||||
QString m_className;
|
||||
QString m_testCase;
|
||||
QString m_formerTestCase;
|
||||
|
@@ -35,6 +35,11 @@ QtTestResult::QtTestResult(const QString &className)
|
||||
{
|
||||
}
|
||||
|
||||
QtTestResult::QtTestResult(const QString &executable, const QString &className)
|
||||
: TestResult(executable, className)
|
||||
{
|
||||
}
|
||||
|
||||
const QString QtTestResult::outputString(bool selected) const
|
||||
{
|
||||
const QString &desc = description();
|
||||
@@ -101,14 +106,14 @@ bool QtTestResult::isIntermediateFor(const TestResult *other) const
|
||||
QTC_ASSERT(other, return false);
|
||||
const QtTestResult *qtOther = static_cast<const QtTestResult *>(other);
|
||||
return m_dataTag == qtOther->m_dataTag && m_function == qtOther->m_function
|
||||
&& name() == qtOther->name();
|
||||
&& name() == qtOther->name() && executable() == qtOther->executable();
|
||||
}
|
||||
|
||||
TestResult *QtTestResult::createIntermediateResultFor(const TestResult *other)
|
||||
{
|
||||
QTC_ASSERT(other, return nullptr);
|
||||
const QtTestResult *qtOther = static_cast<const QtTestResult *>(other);
|
||||
QtTestResult *intermediate = new QtTestResult(qtOther->name());
|
||||
QtTestResult *intermediate = new QtTestResult(qtOther->executable(), qtOther->name());
|
||||
intermediate->m_function = qtOther->m_function;
|
||||
intermediate->m_dataTag = qtOther->m_dataTag;
|
||||
// intermediates will be needed only for data tags
|
||||
|
@@ -34,6 +34,7 @@ class QtTestResult : public TestResult
|
||||
{
|
||||
public:
|
||||
explicit QtTestResult(const QString &className = QString());
|
||||
QtTestResult(const QString &executable, const QString &className);
|
||||
const QString outputString(bool selected) const override;
|
||||
|
||||
void setFunctionName(const QString &functionName) { m_function = functionName; }
|
||||
|
@@ -47,6 +47,12 @@ TestResult::TestResult(const QString &name)
|
||||
{
|
||||
}
|
||||
|
||||
TestResult::TestResult(const QString &executable, const QString &name)
|
||||
: m_executable(executable)
|
||||
, m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
const QString TestResult::outputString(bool selected) const
|
||||
{
|
||||
return selected ? m_description : m_description.split('\n').first();
|
||||
@@ -173,19 +179,21 @@ bool TestResult::isMessageCaseStart(const Result::Type type)
|
||||
bool TestResult::isDirectParentOf(const TestResult *other, bool * /*needsIntermediate*/) const
|
||||
{
|
||||
QTC_ASSERT(other, return false);
|
||||
return m_name == other->m_name;
|
||||
return !m_executable.isEmpty() && m_executable == other->m_executable
|
||||
&& m_name == other->m_name;
|
||||
}
|
||||
|
||||
bool TestResult::isIntermediateFor(const TestResult *other) const
|
||||
{
|
||||
QTC_ASSERT(other, return false);
|
||||
return m_name == other->m_name;
|
||||
return !m_executable.isEmpty() && m_executable == other->m_executable
|
||||
&& m_name == other->m_name;
|
||||
}
|
||||
|
||||
TestResult *TestResult::createIntermediateResultFor(const TestResult *other)
|
||||
{
|
||||
QTC_ASSERT(other, return nullptr);
|
||||
TestResult *intermediate = new TestResult(other->m_name);
|
||||
TestResult *intermediate = new TestResult(other->m_executable, other->m_name);
|
||||
return intermediate;
|
||||
}
|
||||
|
||||
|
@@ -69,12 +69,14 @@ enum Type {
|
||||
class TestResult
|
||||
{
|
||||
public:
|
||||
explicit TestResult();
|
||||
TestResult();
|
||||
explicit TestResult(const QString &name);
|
||||
TestResult(const QString &executable, const QString &name);
|
||||
virtual ~TestResult() {}
|
||||
|
||||
virtual const QString outputString(bool selected) const;
|
||||
|
||||
QString executable() const { return m_executable; }
|
||||
QString name() const { return m_name; }
|
||||
Result::Type result() const { return m_result; }
|
||||
QString description() const { return m_description; }
|
||||
@@ -97,6 +99,7 @@ public:
|
||||
virtual TestResult *createIntermediateResultFor(const TestResult *other);
|
||||
|
||||
private:
|
||||
QString m_executable;
|
||||
QString m_name;
|
||||
Result::Type m_result = Result::Invalid;
|
||||
QString m_description;
|
||||
|
@@ -295,11 +295,13 @@ TestResultItem *TestResultModel::findParentItemFor(const TestResultItem *item,
|
||||
TestResultItem *root = startItem ? const_cast<TestResultItem *>(startItem) : nullptr;
|
||||
const TestResult *result = item->testResult();
|
||||
const QString &name = result->name();
|
||||
const QString &executable = result->executable();
|
||||
|
||||
if (root == nullptr && !name.isEmpty()) {
|
||||
for (int row = rootItem()->childCount() - 1; row >= 0; --row) {
|
||||
TestResultItem *tmp = static_cast<TestResultItem *>(rootItem()->childAt(row));
|
||||
if (tmp->testResult()->name() == name) {
|
||||
auto tmpTestResult = tmp->testResult();
|
||||
if (tmpTestResult->executable() == executable && tmpTestResult->name() == name) {
|
||||
root = tmp;
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user