forked from qt-creator/qt-creator
AutoTest: Fix running test cases with grouping
When gathering information for running tests we need to
take the grouping into account if enabled.
This patch amends 4eabcda3a1.
Task-number: QTCREATORBUG-17979
Change-Id: I27c17a5de8596c95f3b207530560d2a7c2cb5e99
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/asconst.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
namespace Autotest {
|
||||
@@ -122,35 +123,67 @@ TestConfiguration *GTestTreeItem::debugConfiguration() const
|
||||
return config;
|
||||
}
|
||||
|
||||
QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
|
||||
struct TestCases
|
||||
{
|
||||
QStringList filters;
|
||||
int testSetCount = 0;
|
||||
QSet<QString> internalTargets;
|
||||
};
|
||||
|
||||
static void collectTestInfo(const GTestTreeItem *item,
|
||||
QHash<QString, TestCases> &testCasesForProFile,
|
||||
bool ignoreCheckState)
|
||||
{
|
||||
QTC_ASSERT(item, return);
|
||||
if (item->type() == TestTreeItem::GroupNode) {
|
||||
for (int row = 0, count = item->childCount(); row < count; ++row) {
|
||||
auto child = static_cast<const GTestTreeItem *>(item->childItem(row));
|
||||
collectTestInfo(child, testCasesForProFile, ignoreCheckState);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const int childCount = item->childCount();
|
||||
QTC_ASSERT(childCount != 0, return);
|
||||
QTC_ASSERT(item->type() == TestTreeItem::TestCase, return);
|
||||
if (ignoreCheckState || item->checked() == Qt::Checked) {
|
||||
const QString &projectFile = item->childItem(0)->proFile();
|
||||
testCasesForProFile[projectFile].filters.append(
|
||||
gtestFilter(item->state()).arg(item->name()).arg('*'));
|
||||
testCasesForProFile[projectFile].testSetCount += childCount - 1;
|
||||
testCasesForProFile[projectFile].internalTargets.unite(item->internalTargets());
|
||||
} else if (item->checked() == Qt::PartiallyChecked) {
|
||||
for (int childRow = 0; childRow < childCount; ++childRow) {
|
||||
const TestTreeItem *child = item->childItem(childRow);
|
||||
QTC_ASSERT(child->type() == TestTreeItem::TestFunctionOrSet, continue);
|
||||
if (child->checked() == Qt::Checked) {
|
||||
testCasesForProFile[child->proFile()].filters.append(
|
||||
gtestFilter(item->state()).arg(item->name()).arg(child->name()));
|
||||
testCasesForProFile[child->proFile()].internalTargets.unite(
|
||||
child->internalTargets());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<TestConfiguration *> GTestTreeItem::getTestConfigurations(bool ignoreCheckState) const
|
||||
{
|
||||
QList<TestConfiguration *> result;
|
||||
|
||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||
if (!project || type() != Root)
|
||||
return result;
|
||||
|
||||
QHash<QString, int> proFilesWithTestSets;
|
||||
QHash<QString, QSet<QString> > proFilesWithInternalTargets;
|
||||
QHash<QString, TestCases> testCasesForProFile;
|
||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
||||
const GTestTreeItem *child = static_cast<const GTestTreeItem *>(childItem(row));
|
||||
|
||||
const int grandChildCount = child->childCount();
|
||||
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
|
||||
const TestTreeItem *grandChild = child->childItem(grandChildRow);
|
||||
const QString &key = grandChild->proFile();
|
||||
proFilesWithTestSets.insert(key, proFilesWithTestSets[key] + 1);
|
||||
proFilesWithInternalTargets[key].unite(grandChild->internalTargets());
|
||||
}
|
||||
auto child = static_cast<const GTestTreeItem *>(childItem(row));
|
||||
collectTestInfo(child, testCasesForProFile, ignoreCheckState);
|
||||
}
|
||||
|
||||
QHash<QString, int>::ConstIterator it = proFilesWithTestSets.begin();
|
||||
QHash<QString, int>::ConstIterator end = proFilesWithTestSets.end();
|
||||
for ( ; it != end; ++it) {
|
||||
const QSet<QString> &internalTargets = proFilesWithInternalTargets[it.key()];
|
||||
for (const QString &target : internalTargets) {
|
||||
for (auto it = testCasesForProFile.begin(), end = testCasesForProFile.end(); it != end; ++it) {
|
||||
for (const QString &target : Utils::asConst(it.value().internalTargets)) {
|
||||
GTestConfiguration *tc = new GTestConfiguration;
|
||||
tc->setTestCaseCount(it.value());
|
||||
if (!ignoreCheckState)
|
||||
tc->setTestCases(it.value().filters);
|
||||
tc->setTestCaseCount(tc->testCaseCount() + it.value().testSetCount);
|
||||
tc->setProjectFile(it.key());
|
||||
tc->setProject(project);
|
||||
tc->setInternalTarget(target);
|
||||
@@ -161,69 +194,14 @@ QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
|
||||
return result;
|
||||
}
|
||||
|
||||
struct TestCases
|
||||
QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
|
||||
{
|
||||
QStringList filters;
|
||||
int additionalTestCaseCount = 0;
|
||||
};
|
||||
return getTestConfigurations(true);
|
||||
}
|
||||
|
||||
QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
|
||||
{
|
||||
QList<TestConfiguration *> result;
|
||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||
if (!project || type() != Root)
|
||||
return result;
|
||||
|
||||
QHash<QString, TestCases> proFilesWithCheckedTestSets;
|
||||
QHash<QString, QSet<QString> > proFilesWithInternalTargets;
|
||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
||||
const GTestTreeItem *child = static_cast<const GTestTreeItem *>(childItem(row));
|
||||
|
||||
const int grandChildCount = child->childCount();
|
||||
QTC_ASSERT(grandChildCount != 0, continue);
|
||||
|
||||
switch (child->checked()) {
|
||||
case Qt::Unchecked:
|
||||
continue;
|
||||
case Qt::Checked: {
|
||||
auto &testCases = proFilesWithCheckedTestSets[child->childItem(0)->proFile()];
|
||||
testCases.filters.append(gtestFilter(child->state()).arg(child->name()).arg('*'));
|
||||
testCases.additionalTestCaseCount += grandChildCount - 1;
|
||||
proFilesWithInternalTargets[child->childItem(0)->proFile()].unite(
|
||||
child->internalTargets());
|
||||
break;
|
||||
}
|
||||
case Qt::PartiallyChecked: {
|
||||
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
|
||||
const TestTreeItem *grandChild = child->childItem(grandChildRow);
|
||||
if (grandChild->checked() == Qt::Checked) {
|
||||
proFilesWithCheckedTestSets[grandChild->proFile()].filters.append(
|
||||
gtestFilter(child->state()).arg(child->name()).arg(grandChild->name()));
|
||||
proFilesWithInternalTargets[grandChild->proFile()].unite(
|
||||
grandChild->internalTargets());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, TestCases>::ConstIterator it = proFilesWithCheckedTestSets.begin();
|
||||
QHash<QString, TestCases>::ConstIterator end = proFilesWithCheckedTestSets.end();
|
||||
for ( ; it != end; ++it) {
|
||||
const QSet<QString> &internalTargets = proFilesWithInternalTargets[it.key()];
|
||||
for (const QString &target : internalTargets) {
|
||||
GTestConfiguration *tc = new GTestConfiguration;
|
||||
tc->setTestCases(it.value().filters);
|
||||
tc->setTestCaseCount(tc->testCaseCount() + it.value().additionalTestCaseCount);
|
||||
tc->setProjectFile(it.key());
|
||||
tc->setProject(project);
|
||||
tc->setInternalTarget(target);
|
||||
result << tc;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return getTestConfigurations(false);
|
||||
}
|
||||
|
||||
TestTreeItem *GTestTreeItem::find(const TestParseResult *result)
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
|
||||
private:
|
||||
bool modifyTestSetContent(const GTestParseResult *result);
|
||||
QList<TestConfiguration *> getTestConfigurations(bool ignoreCheckState) const;
|
||||
GTestTreeItem::TestStates m_state;
|
||||
};
|
||||
|
||||
|
||||
@@ -139,6 +139,53 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
|
||||
return config;
|
||||
}
|
||||
|
||||
static void fillTestConfigurationsFromCheckState(const TestTreeItem *item,
|
||||
QList<TestConfiguration *> &testConfigurations)
|
||||
{
|
||||
QTC_ASSERT(item, return);
|
||||
if (item->type() == TestTreeItem::GroupNode) {
|
||||
for (int row = 0, count = item->childCount(); row < count; ++row)
|
||||
fillTestConfigurationsFromCheckState(item->childItem(row), testConfigurations);
|
||||
return;
|
||||
}
|
||||
QTC_ASSERT(item->type() == TestTreeItem::TestCase, return);
|
||||
QtTestConfiguration *testConfig = nullptr;
|
||||
switch (item->checked()) {
|
||||
case Qt::Unchecked:
|
||||
return;
|
||||
case Qt::Checked:
|
||||
testConfig = static_cast<QtTestConfiguration *>(item->testConfiguration());
|
||||
QTC_ASSERT(testConfig, return);
|
||||
testConfigurations << testConfig;
|
||||
return;
|
||||
case Qt::PartiallyChecked:
|
||||
default:
|
||||
int grandChildCount = item->childCount();
|
||||
QStringList testCases;
|
||||
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
|
||||
const TestTreeItem *grandChild = item->childItem(grandChildRow);
|
||||
if (grandChild->checked() == Qt::Checked) {
|
||||
testCases << grandChild->name();
|
||||
} else if (grandChild->checked() == Qt::PartiallyChecked) {
|
||||
const int dtCount = grandChild->childCount();
|
||||
const QString funcName = grandChild->name();
|
||||
for (int dtRow = 0; dtRow < dtCount; ++dtRow) {
|
||||
const TestTreeItem *dataTag = grandChild->childItem(dtRow);
|
||||
if (dataTag->checked() == Qt::Checked)
|
||||
testCases << funcName + ':' + dataTag->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testConfig = new QtTestConfiguration();
|
||||
testConfig->setTestCases(testCases);
|
||||
testConfig->setProjectFile(item->proFile());
|
||||
testConfig->setProject(ProjectExplorer::SessionManager::startupProject());
|
||||
testConfig->setInternalTargets(item->internalTargets());
|
||||
testConfigurations << testConfig;
|
||||
}
|
||||
}
|
||||
|
||||
TestConfiguration *QtTestTreeItem::debugConfiguration() const
|
||||
{
|
||||
QtTestConfiguration *config = static_cast<QtTestConfiguration *>(testConfiguration());
|
||||
@@ -157,13 +204,19 @@ QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
|
||||
|
||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
||||
const TestTreeItem *child = childItem(row);
|
||||
|
||||
TestConfiguration *tc = new QtTestConfiguration();
|
||||
tc->setTestCaseCount(child->childCount());
|
||||
tc->setProjectFile(child->proFile());
|
||||
tc->setProject(project);
|
||||
tc->setInternalTargets(child->internalTargets());
|
||||
TestConfiguration *tc = nullptr;
|
||||
if (child->type() == TestCase) {
|
||||
tc = child->testConfiguration();
|
||||
QTC_ASSERT(tc, continue);
|
||||
result << tc;
|
||||
} else if (child->type() == GroupNode) {
|
||||
const int groupChildCount = child->childCount();
|
||||
for (int groupChildRow = 0; groupChildRow < groupChildCount; ++groupChildRow) {
|
||||
tc = child->childItem(groupChildRow)->testConfiguration();
|
||||
QTC_ASSERT(tc, continue);
|
||||
result << tc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -175,49 +228,8 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
|
||||
if (!project || type() != Root)
|
||||
return result;
|
||||
|
||||
QtTestConfiguration *testConfiguration = nullptr;
|
||||
|
||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
||||
const TestTreeItem *child = childItem(row);
|
||||
|
||||
switch (child->checked()) {
|
||||
case Qt::Unchecked:
|
||||
continue;
|
||||
case Qt::Checked:
|
||||
testConfiguration = new QtTestConfiguration();
|
||||
testConfiguration->setTestCaseCount(child->childCount());
|
||||
testConfiguration->setProjectFile(child->proFile());
|
||||
testConfiguration->setProject(project);
|
||||
testConfiguration->setInternalTargets(child->internalTargets());
|
||||
result << testConfiguration;
|
||||
continue;
|
||||
case Qt::PartiallyChecked:
|
||||
default:
|
||||
int grandChildCount = child->childCount();
|
||||
QStringList testCases;
|
||||
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
|
||||
const TestTreeItem *grandChild = child->childItem(grandChildRow);
|
||||
if (grandChild->checked() == Qt::Checked) {
|
||||
testCases << grandChild->name();
|
||||
} else if (grandChild->checked() == Qt::PartiallyChecked) {
|
||||
const int dtCount = grandChild->childCount();
|
||||
const QString funcName = grandChild->name();
|
||||
for (int dtRow = 0; dtRow < dtCount; ++dtRow) {
|
||||
const TestTreeItem *dataTag = grandChild->childItem(dtRow);
|
||||
if (dataTag->checked() == Qt::Checked)
|
||||
testCases << funcName + ':' + dataTag->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testConfiguration = new QtTestConfiguration();
|
||||
testConfiguration->setTestCases(testCases);
|
||||
testConfiguration->setProjectFile(child->proFile());
|
||||
testConfiguration->setProject(project);
|
||||
testConfiguration->setInternalTargets(child->internalTargets());
|
||||
result << testConfiguration;
|
||||
}
|
||||
}
|
||||
for (int row = 0, count = childCount(); row < count; ++row)
|
||||
fillTestConfigurationsFromCheckState(childItem(row), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -153,6 +153,43 @@ TestConfiguration *QuickTestTreeItem::testConfiguration() const
|
||||
return config;
|
||||
}
|
||||
|
||||
static void testConfigurationFromCheckState(const TestTreeItem *item,
|
||||
QHash<QString, QuickTestConfiguration *> &foundProFiles)
|
||||
{
|
||||
QTC_ASSERT(item, return);
|
||||
if (item->type() == TestTreeItem::GroupNode) {
|
||||
for (int row = 0, count = item->childCount(); row < count; ++row)
|
||||
testConfigurationFromCheckState(item->childItem(row), foundProFiles);
|
||||
return;
|
||||
}
|
||||
QTC_ASSERT(item->type() == TestTreeItem::TestCase, return);
|
||||
QuickTestConfiguration *tc = nullptr;
|
||||
if (item->checked() == Qt::Unchecked)
|
||||
return;
|
||||
|
||||
QStringList testFunctions;
|
||||
const int childCount = item->childCount();
|
||||
for (int childRow = 0; childRow < childCount; ++childRow) {
|
||||
const TestTreeItem *child = item->childItem(childRow);
|
||||
if (child->checked() != Qt::Checked || child->type() != TestTreeItem::TestFunctionOrSet)
|
||||
continue;
|
||||
testFunctions << item->name() + "::" + child->name();
|
||||
}
|
||||
if (foundProFiles.contains(item->proFile())) {
|
||||
tc = foundProFiles[item->proFile()];
|
||||
QStringList oldFunctions(tc->testCases());
|
||||
oldFunctions << testFunctions;
|
||||
tc->setTestCases(oldFunctions);
|
||||
} else {
|
||||
tc = new QuickTestConfiguration;
|
||||
tc->setTestCases(testFunctions);
|
||||
tc->setProjectFile(item->proFile());
|
||||
tc->setProject(ProjectExplorer::SessionManager::startupProject());
|
||||
tc->setInternalTargets(item->internalTargets());
|
||||
foundProFiles.insert(item->proFile(), tc);
|
||||
}
|
||||
}
|
||||
|
||||
TestConfiguration *QuickTestTreeItem::debugConfiguration() const
|
||||
{
|
||||
QuickTestConfiguration *config = static_cast<QuickTestConfiguration *>(testConfiguration());
|
||||
@@ -161,6 +198,17 @@ TestConfiguration *QuickTestTreeItem::debugConfiguration() const
|
||||
return config;
|
||||
}
|
||||
|
||||
struct Tests {
|
||||
int testCount = 0;
|
||||
QSet<QString> internalTargets;
|
||||
};
|
||||
|
||||
static void addTestsForItem(Tests &tests, const TestTreeItem *item)
|
||||
{
|
||||
tests.testCount += item->childCount();
|
||||
tests.internalTargets = item->internalTargets();
|
||||
}
|
||||
|
||||
QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
|
||||
{
|
||||
QList<TestConfiguration *> result;
|
||||
@@ -169,8 +217,7 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
|
||||
if (!project || type() != Root)
|
||||
return result;
|
||||
|
||||
QHash<QString, int> foundProFiles;
|
||||
QHash<QString, QSet<QString> > proFilesWithTargets;
|
||||
QHash<QString, Tests> testsForProfile;
|
||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
||||
const TestTreeItem *child = childItem(row);
|
||||
// unnamed Quick Tests must be handled separately
|
||||
@@ -178,25 +225,29 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
|
||||
for (int childRow = 0, ccount = child->childCount(); childRow < ccount; ++ childRow) {
|
||||
const TestTreeItem *grandChild = child->childItem(childRow);
|
||||
const QString &proFile = grandChild->proFile();
|
||||
foundProFiles.insert(proFile, foundProFiles[proFile] + 1);
|
||||
proFilesWithTargets.insert(proFile, grandChild->internalTargets());
|
||||
++(testsForProfile[proFile].testCount);
|
||||
testsForProfile[proFile].internalTargets = grandChild->internalTargets();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// named Quick Test
|
||||
const QString &proFile = child->proFile();
|
||||
foundProFiles.insert(proFile, foundProFiles[proFile] + child->childCount());
|
||||
proFilesWithTargets.insert(proFile, child->internalTargets());
|
||||
if (child->type() == TestCase) {
|
||||
addTestsForItem(testsForProfile[child->proFile()], child);
|
||||
} else if (child->type() == GroupNode) {
|
||||
const int groupCount = child->childCount();
|
||||
for (int groupRow = 0; groupRow < groupCount; ++groupRow) {
|
||||
const TestTreeItem *grandChild = child->childItem(groupRow);
|
||||
addTestsForItem(testsForProfile[grandChild->proFile()], grandChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
// create TestConfiguration for each project file
|
||||
QHash<QString, int>::ConstIterator it = foundProFiles.begin();
|
||||
QHash<QString, int>::ConstIterator end = foundProFiles.end();
|
||||
for ( ; it != end; ++it) {
|
||||
for (auto it = testsForProfile.begin(), end = testsForProfile.end(); it != end; ++it) {
|
||||
QuickTestConfiguration *tc = new QuickTestConfiguration;
|
||||
tc->setTestCaseCount(it.value());
|
||||
tc->setTestCaseCount(it.value().testCount);
|
||||
tc->setProjectFile(it.key());
|
||||
tc->setProject(project);
|
||||
tc->setInternalTargets(proFilesWithTargets[it.key()]);
|
||||
tc->setInternalTargets(it.value().internalTargets);
|
||||
result << tc;
|
||||
}
|
||||
return result;
|
||||
@@ -209,7 +260,6 @@ QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() co
|
||||
if (!project || type() != Root)
|
||||
return result;
|
||||
|
||||
QuickTestConfiguration *tc = nullptr;
|
||||
QHash<QString, QuickTestConfiguration *> foundProFiles;
|
||||
|
||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
||||
@@ -219,39 +269,10 @@ QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() co
|
||||
continue;
|
||||
|
||||
// named Quick Tests
|
||||
switch (child->checked()) {
|
||||
case Qt::Unchecked:
|
||||
continue;
|
||||
case Qt::Checked:
|
||||
case Qt::PartiallyChecked:
|
||||
default:
|
||||
QStringList testFunctions;
|
||||
int grandChildCount = child->childCount();
|
||||
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
|
||||
const TestTreeItem *grandChild = child->childItem(grandChildRow);
|
||||
if (grandChild->checked() != Qt::Checked || grandChild->type() != TestFunctionOrSet)
|
||||
continue;
|
||||
testFunctions << child->name() + "::" + grandChild->name();
|
||||
testConfigurationFromCheckState(child, foundProFiles);
|
||||
}
|
||||
if (foundProFiles.contains(child->proFile())) {
|
||||
tc = foundProFiles[child->proFile()];
|
||||
QStringList oldFunctions(tc->testCases());
|
||||
oldFunctions << testFunctions;
|
||||
tc->setTestCases(oldFunctions);
|
||||
} else {
|
||||
tc = new QuickTestConfiguration;
|
||||
tc->setTestCases(testFunctions);
|
||||
tc->setProjectFile(child->proFile());
|
||||
tc->setProject(project);
|
||||
tc->setInternalTargets(child->internalTargets());
|
||||
foundProFiles.insert(child->proFile(), tc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
QHash<QString, QuickTestConfiguration *>::ConstIterator it = foundProFiles.begin();
|
||||
QHash<QString, QuickTestConfiguration *>::ConstIterator end = foundProFiles.end();
|
||||
for ( ; it != end; ++it) {
|
||||
|
||||
for (auto it = foundProFiles.begin(), end = foundProFiles.end(); it != end; ++it) {
|
||||
QuickTestConfiguration *config = it.value();
|
||||
if (!config->unnamedOnly())
|
||||
result << config;
|
||||
|
||||
Reference in New Issue
Block a user