diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp
index 06db3c0cda370e0b2c5f861021dc6c0b3b01c9e6..540f7c6679db7589d46b2fa121d18230161c69d2 100644
--- a/src/plugins/autotest/gtest/gtesttreeitem.cpp
+++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp
@@ -88,9 +88,6 @@ TestConfiguration *GTestTreeItem::testConfiguration() const
             config->setTestCaseCount(count);
             config->setProjectFile(proFile());
             config->setProject(project);
-            // item has no filePath set - so take it of the first children
-            config->setDisplayName(
-                    TestUtils::getCMakeDisplayNameIfNecessary(childItem(0)->filePath(), proFile()));
         }
         break;
     }
@@ -103,8 +100,6 @@ TestConfiguration *GTestTreeItem::testConfiguration() const
         config->setTestCases(QStringList(testSpecifier));
         config->setProjectFile(proFile());
         config->setProject(project);
-        config->setDisplayName(
-                    TestUtils::getCMakeDisplayNameIfNecessary(filePath(), parent->proFile()));
         break;
     }
     default:
@@ -179,7 +174,6 @@ QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
         GTestConfiguration *tc = new GTestConfiguration;
         tc->setTestCaseCount(it.value());
         tc->setProjectFile(key.proFile);
-        tc->setDisplayName(key.displayName);
         tc->setProject(project);
         result << tc;
     }
@@ -244,7 +238,6 @@ QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
         tc->setTestCases(it.value().filters);
         tc->setTestCaseCount(tc->testCaseCount() + it.value().additionalTestCaseCount);
         tc->setProjectFile(proFileWithDisplayName.proFile);
-        tc->setDisplayName(proFileWithDisplayName.displayName);
         tc->setProject(project);
         result << tc;
     }
diff --git a/src/plugins/autotest/qtest/qttesttreeitem.cpp b/src/plugins/autotest/qtest/qttesttreeitem.cpp
index b4d226253a79676a761134c06196c356f0bdd35d..9236b79631364ff05e3e27add48cfefec6db36d0 100644
--- a/src/plugins/autotest/qtest/qttesttreeitem.cpp
+++ b/src/plugins/autotest/qtest/qttesttreeitem.cpp
@@ -111,7 +111,6 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
         config->setTestCaseCount(childCount());
         config->setProjectFile(proFile());
         config->setProject(project);
-        config->setDisplayName(TestUtils::getCMakeDisplayNameIfNecessary(filePath(), proFile()));
         break;
     case TestFunctionOrSet: {
         TestTreeItem *parent = parentItem();
@@ -119,8 +118,6 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
         config->setTestCases(QStringList(name()));
         config->setProjectFile(parent->proFile());
         config->setProject(project);
-        config->setDisplayName(
-                TestUtils::getCMakeDisplayNameIfNecessary(filePath(), parent->proFile()));
         break;
     }
     case TestDataTag: {
@@ -133,8 +130,6 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
         config->setTestCases(QStringList(functionWithTag));
         config->setProjectFile(parent->proFile());
         config->setProject(project);
-        config->setDisplayName(TestUtils::getCMakeDisplayNameIfNecessary(filePath(),
-                                                                         parent->proFile()));
         break;
     }
     default:
@@ -166,8 +161,6 @@ QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
         tc->setTestCaseCount(child->childCount());
         tc->setProjectFile(child->proFile());
         tc->setProject(project);
-        tc->setDisplayName(TestUtils::getCMakeDisplayNameIfNecessary(child->filePath(),
-                                                                     child->proFile()));
         result << tc;
     }
     return result;
@@ -193,8 +186,6 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
             testConfiguration->setTestCaseCount(child->childCount());
             testConfiguration->setProjectFile(child->proFile());
             testConfiguration->setProject(project);
-            testConfiguration->setDisplayName(
-                    TestUtils::getCMakeDisplayNameIfNecessary(child->filePath(), child->proFile()));
             result << testConfiguration;
             continue;
         case Qt::PartiallyChecked:
@@ -220,8 +211,6 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
             testConfiguration->setTestCases(testCases);
             testConfiguration->setProjectFile(child->proFile());
             testConfiguration->setProject(project);
-            testConfiguration->setDisplayName(
-                    TestUtils::getCMakeDisplayNameIfNecessary(child->filePath(), child->proFile()));
             result << testConfiguration;
         }
     }
diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp
index c5d0c8d86a011d59813d4f3e4f68bb68bd3523fd..6b1b710170142727b14e9cc7a8af7e6576c8346c 100644
--- a/src/plugins/autotest/testconfiguration.cpp
+++ b/src/plugins/autotest/testconfiguration.cpp
@@ -54,30 +54,6 @@ TestConfiguration::~TestConfiguration()
     m_testCases.clear();
 }
 
-void completeBasicProjectInformation(Project *project, const QString &proFile, QString *displayName,
-                             Project **targetProject)
-{
-    CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
-    QVector<CppTools::ProjectPart::Ptr> projParts = cppMM->projectInfo(project).projectParts();
-
-    if (displayName->isEmpty()) {
-        foreach (const CppTools::ProjectPart::Ptr &part, projParts) {
-            if (part->projectFile == proFile) {
-                *displayName = part->displayName;
-                *targetProject = part->project;
-                return;
-            }
-        }
-    } else { // for CMake based projects we've got the displayname already
-        foreach (const CppTools::ProjectPart::Ptr &part, projParts) {
-            if (part->displayName == *displayName) {
-                *targetProject = part->project;
-                return;
-            }
-        }
-    }
-}
-
 static bool isLocal(RunConfiguration *runConfiguration)
 {
     Target *target = runConfiguration ? runConfiguration->target() : 0;
@@ -93,106 +69,80 @@ void TestConfiguration::completeTestInformation(int runMode)
     if (!project)
         return;
 
-    QString executable;
-    QString targetName;
-    QString workDir;
-    QString displayName = m_displayName;
-    QString buildDir;
-    Project *targetProject = 0;
-    Utils::Environment env;
-    Target *runConfigTarget = 0;
-    bool hasDesktopTarget = false;
-    bool guessedRunConfiguration = false;
-    setProject(0);
-
-    completeBasicProjectInformation(project, m_projectFile, &displayName, &targetProject);
-
     Target *target = project->activeTarget();
     if (!target)
         return;
 
-    BuildTargetInfoList appTargets = target->applicationTargets();
-    if (m_displayName.isEmpty()) {
-        foreach (const BuildTargetInfo &bti, appTargets.list) {
-            // some project manager store line/column information as well inside ProjectPart
-            if (bti.isValid() && m_projectFile.startsWith(bti.projectFilePath.toString())) {
-                executable = bti.targetFilePath.toString();
-                if (Utils::HostOsInfo::isWindowsHost() && !executable.toLower().endsWith(".exe"))
-                    executable = Utils::HostOsInfo::withExecutableSuffix(executable);
-                targetName = bti.targetName;
-                break;
-            }
-        }
-    } else { // CMake based projects have no specific pro file, but target name matches displayname
-        foreach (const BuildTargetInfo &bti, appTargets.list) {
-            if (bti.isValid() && m_displayName == bti.targetName) {
-                // for CMake base projects targetFilePath has executable suffix already
-                executable = bti.targetFilePath.toString();
-                targetName = m_displayName;
-                break;
-            }
-        }
-    }
-
-    if (targetProject) {
-        if (auto buildConfig = target->activeBuildConfiguration()) {
-            const QString buildBase = buildConfig->buildDirectory().toString();
-            const QString projBase = targetProject->projectDirectory().toString();
-            if (m_projectFile.startsWith(projBase))
-                buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath();
-        }
-    }
-
-    QList<RunConfiguration *> rcs = target->runConfigurations();
-    foreach (RunConfiguration *rc, rcs) {
-        Runnable runnable = rc->runnable();
-        if (isLocal(rc) && runnable.is<StandardRunnable>()) {
+    const auto cppMM = CppTools::CppModelManager::instance();
+    const QVector<CppTools::ProjectPart::Ptr> projectParts = cppMM->projectInfo(project).projectParts();
+    const QVector<CppTools::ProjectPart::Ptr> relevantParts
+            = Utils::filtered(projectParts, [this] (const CppTools::ProjectPart::Ptr &part) {
+        return part->selectedForBuilding && part->projectFile == m_projectFile;
+    });
+    const QSet<QString> buildSystemTargets
+            = Utils::transform<QSet>(relevantParts, [] (const CppTools::ProjectPart::Ptr &part) {
+        return part->buildSystemTarget;
+    });
+
+    const BuildTargetInfo targetInfo
+            = Utils::findOrDefault(target->applicationTargets().list, [&buildSystemTargets] (const BuildTargetInfo &bti) {
+        return buildSystemTargets.contains(bti.targetName);
+    });
+    const Utils::FileName executable = targetInfo.targetFilePath; // empty if BTI is default created
+    for (RunConfiguration *runConfig : target->runConfigurations()) {
+        if (!isLocal(runConfig)) // TODO add device support
+            continue;
+
+        if (buildSystemTargets.contains(runConfig->buildSystemTarget())) {
+            Runnable runnable = runConfig->runnable();
+            if (!runnable.is<StandardRunnable>())
+                continue;
             StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
-            // we might have an executable that gets installed - in such a case the
-            // runnable's executable and executable won't match - but the (unique) display name
-            // of the run configuration should match targetName
-            if (stdRunnable.executable == executable
-                    || (!targetName.isEmpty() && rc->displayName() == targetName)) {
-                executable = stdRunnable.executable;
-                workDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory);
-                env = stdRunnable.environment;
-                hasDesktopTarget = true;
-                runConfigTarget = rc->target();
-                break;
-            }
+            // TODO this might pick up the wrong executable
+            m_executableFile = stdRunnable.executable;
+            m_displayName = runConfig->displayName();
+            m_workingDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory);
+            m_environment = stdRunnable.environment;
+            m_project = project;
+            if (runMode == TestRunner::Debug)
+                m_runConfig = new TestRunConfiguration(runConfig->target(), this);
+            break;
         }
     }
-
-    // if we could not figure out the run configuration
-    // try to use the run configuration of the parent project
-    if (!hasDesktopTarget && targetProject && !executable.isEmpty()) {
+    // RunConfiguration for this target could be explicitly removed or not created at all
+    if (m_displayName.isEmpty() && !executable.isEmpty()) {
+        // we failed to find a valid runconfiguration - but we've got the executable already
         if (auto rc = target->activeRunConfiguration()) {
-            Runnable runnable = rc->runnable();
-            if (isLocal(rc) && runnable.is<StandardRunnable>()) {
-                StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
-                workDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory);
-                env = stdRunnable.environment;
-                hasDesktopTarget = true;
-                guessedRunConfiguration = true;
-                runConfigTarget = rc->target();
+            if (isLocal(rc)) { // FIXME for now only Desktop support
+                Runnable runnable = rc->runnable();
+                if (runnable.is<StandardRunnable>()) {
+                    StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
+                    m_environment = stdRunnable.environment;
+                    // when guessing we might have no extension
+                    const QString &exeString = executable.toString();
+                    if (Utils::HostOsInfo::isWindowsHost() && !exeString.toLower().endsWith(".exe"))
+                        m_executableFile = Utils::HostOsInfo::withExecutableSuffix(exeString);
+                    else
+                        m_executableFile = exeString;
+                    m_project = project;
+                    m_guessedConfiguration = true;
+                    if (runMode == TestRunner::Debug)
+                        m_runConfig = new TestRunConfiguration(rc->target(), this);
+                }
             }
         }
     }
 
-    setDisplayName(displayName);
-
-    if (hasDesktopTarget) {
-        setExecutableFile(executable);
-        setWorkingDirectory(workDir);
-        setBuildDirectory(buildDir);
-        setEnvironment(env);
-        setProject(project);
-        setGuessedConfiguration(guessedRunConfiguration);
-        if (runMode == TestRunner::Debug)
-            m_runConfig = new TestRunConfiguration(runConfigTarget, this);
+    if (auto buildConfig = target->activeBuildConfiguration()) {
+        const QString buildBase = buildConfig->buildDirectory().toString();
+        const QString projBase = project->projectDirectory().toString();
+        if (m_projectFile.startsWith(projBase))
+            m_buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath();
     }
-}
 
+    if (m_displayName.isEmpty()) // happens e.g. when guessing the TestConfiguration or error
+        m_displayName = buildSystemTargets.isEmpty() ? "unknown" : *buildSystemTargets.begin();
+}
 
 /**
  * @brief sets the test cases for this test configuration.