diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp
index be02d0f671b891e8b8819a6514094c1810cdf510..14855097b90a728a2341f5ae3b611c3dcc312746 100644
--- a/src/libs/extensionsystem/pluginmanager.cpp
+++ b/src/libs/extensionsystem/pluginmanager.cpp
@@ -869,6 +869,77 @@ void PluginManagerPrivate::deleteAll()
     }
 }
 
+static QStringList testFunctions(const QMetaObject *metaObject)
+{
+    QStringList testFunctions;
+
+    for (int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i) {
+        const QByteArray signature = metaObject->method(i).methodSignature();
+        if (signature.startsWith("test") && !signature.endsWith("_data()")) {
+            const QString method = QString::fromLatin1(signature);
+            const QString methodName = method.left(method.size() - 2);
+            testFunctions.append(methodName);
+        }
+    }
+
+    return testFunctions;
+}
+
+static QStringList testFunctionsWantedByUser(const PluginSpec *pluginSpec,
+                                             const QStringList &availableTestFunctions,
+                                             const QStringList &testFunctionsSpecs)
+{
+    QStringList testFunctions;
+
+    foreach (const QString &userTestFunction, testFunctionsSpecs) {
+        // There might be a test data suffix like in "testfunction:testdata1".
+        QString testFunctionName = userTestFunction;
+        QString testDataSuffix;
+        const int index = testFunctionName.indexOf(QLatin1Char(':'));
+        if (index != -1) {
+            testDataSuffix = testFunctionName.mid(index);
+            testFunctionName = testFunctionName.left(index);
+        }
+
+        const QRegExp regExp(testFunctionName, Qt::CaseSensitive, QRegExp::Wildcard);
+        QStringList matchingFunctions;
+        foreach (const QString &testFunction, availableTestFunctions) {
+            if (regExp.exactMatch(testFunction))
+                matchingFunctions.append(testFunction);
+        }
+        if (!matchingFunctions.isEmpty()) {
+            // If the specified test data is invalid, the QTest framework will
+            // print a reasonable error message for us.
+            foreach (const QString &matchingFunction, matchingFunctions)
+                testFunctions.append(matchingFunction + testDataSuffix);
+        } else {
+            QTextStream out(stdout);
+            out << "No test function matches \"" << testFunctionName
+                << "\" for plugin \"" << pluginSpec->name() << "\"." << endl
+                << "  Available test functions for plugin \"" << pluginSpec->name()
+                << "\" are:" << endl;
+            foreach (const QString &testFunction, availableTestFunctions)
+                out << "    " << testFunction << endl;
+        }
+    }
+
+    return testFunctions;
+}
+
+static int executeTestFunctions(QObject *testObject, const QStringList &functions)
+{
+    // Don't run QTest::qExec without any test functions, that'd run *all* slots as tests.
+    if (functions.isEmpty())
+        return 0;
+
+    // QTest::qExec() expects basically QCoreApplication::arguments(),
+    QStringList qExecArguments = QStringList()
+            << QLatin1String("arg0") // fake application name
+            << QLatin1String("-maxwarnings") << QLatin1String("0"); // unlimit output
+    qExecArguments << functions;
+    return QTest::qExec(testObject, qExecArguments);
+}
+
 void PluginManagerPrivate::startTests()
 {
     if (PluginManager::hasError()) {
@@ -885,69 +956,20 @@ void PluginManagerPrivate::startTests()
             continue;
 
         // Collect all test functions of the plugin.
-        QStringList allTestFunctions;
-        const QMetaObject *metaObject = pluginSpec->plugin()->metaObject();
-
-        for (int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i) {
-            const QByteArray signature = metaObject->method(i).methodSignature();
-            if (signature.startsWith("test") && !signature.endsWith("_data()")) {
-                const QString method = QString::fromLatin1(signature);
-                const QString methodName = method.left(method.size() - 2);
-                allTestFunctions.append(methodName);
-            }
-        }
+        const QStringList allTestFunctions = testFunctions(pluginSpec->plugin()->metaObject());
 
         QStringList testFunctionsToExecute;
-
         // User did not specify any test functions, so add every test function.
         if (testSpec.testFunctions.isEmpty()) {
             testFunctionsToExecute = allTestFunctions;
 
         // User specified test functions. Add them if they are valid.
         } else {
-            foreach (const QString &userTestFunction, testSpec.testFunctions) {
-                // There might be a test data suffix like in "testfunction:testdata1".
-                QString testFunctionName = userTestFunction;
-                QString testDataSuffix;
-                const int index = testFunctionName.indexOf(QLatin1Char(':'));
-                if (index != -1) {
-                    testDataSuffix = testFunctionName.mid(index);
-                    testFunctionName = testFunctionName.left(index);
-                }
-
-                const QRegExp regExp(testFunctionName, Qt::CaseSensitive, QRegExp::Wildcard);
-                QStringList matchingFunctions;
-                foreach (const QString &testFunction, allTestFunctions) {
-                    if (regExp.exactMatch(testFunction))
-                        matchingFunctions.append(testFunction);
-                }
-                if (!matchingFunctions.isEmpty()) {
-                    // If the specified test data is invalid, the QTest framework will
-                    // print a reasonable error message for us.
-                    foreach (const QString &matchingFunction, matchingFunctions)
-                        testFunctionsToExecute.append(matchingFunction + testDataSuffix);
-                } else {
-                    QTextStream out(stdout);
-                    out << "No test function matches \"" << testFunctionName
-                        << "\" for plugin \"" << pluginSpec->name() << "\"." << endl
-                        << "  Available test functions for plugin \"" << pluginSpec->name()
-                        << "\" are:" << endl;
-                    foreach (const QString &testFunction, allTestFunctions)
-                        out << "    " << testFunction << endl;
-                }
-            }
+            testFunctionsToExecute = testFunctionsWantedByUser(pluginSpec, allTestFunctions,
+                                                               testSpec.testFunctions);
         }
 
-        // Don't run QTest::qExec without any test functions, that'd run
-        // *all* slots as tests.
-        if (!testFunctionsToExecute.isEmpty()) {
-            // QTest::qExec() expects basically QCoreApplication::arguments(),
-            QStringList qExecArguments = QStringList()
-                << QLatin1String("arg0") // fake application name
-                << QLatin1String("-maxwarnings") << QLatin1String("0"); // unlimit output
-            qExecArguments << testFunctionsToExecute;
-            m_failedTests += QTest::qExec(pluginSpec->plugin(), qExecArguments);
-        }
+        m_failedTests += executeTestFunctions(pluginSpec->plugin(), testFunctionsToExecute);
     }
     if (!testSpecs.isEmpty())
         QTimer::singleShot(1, this, SLOT(exitWithNumberOfFailedTests()));