diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp
index e770b238f00981ee86b50ab973765e44a6e7c215..3c0463ec1b48ec5b1219d3a2d0d4cf5ae776a034 100644
--- a/src/plugins/autotest/testconfiguration.cpp
+++ b/src/plugins/autotest/testconfiguration.cpp
@@ -28,6 +28,7 @@
 #include <cpptools/cppmodelmanager.h>
 #include <cpptools/projectinfo.h>
 
+#include <projectexplorer/buildconfiguration.h>
 #include <projectexplorer/buildtargetinfo.h>
 #include <projectexplorer/environmentaspect.h>
 #include <projectexplorer/kitinformation.h>
@@ -115,6 +116,7 @@ void TestConfiguration::completeTestInformation()
     QString workDir;
     QString proFile = m_proFile;
     QString displayName;
+    QString buildDir;
     Project *targetProject = 0;
     Utils::Environment env;
     bool hasDesktopTarget = false;
@@ -140,6 +142,15 @@ void TestConfiguration::completeTestInformation()
         }
     }
 
+    if (targetProject) {
+        if (auto buildConfig = target->activeBuildConfiguration()) {
+            const QString buildBase = buildConfig->buildDirectory().toString();
+            const QString projBase = targetProject->projectDirectory().toString();
+            if (proFile.startsWith(projBase))
+                buildDir = QFileInfo(buildBase + proFile.mid(projBase.length())).absolutePath();
+        }
+    }
+
     QList<RunConfiguration *> rcs = target->runConfigurations();
     foreach (RunConfiguration *rc, rcs) {
         Runnable runnable = rc->runnable();
@@ -176,6 +187,7 @@ void TestConfiguration::completeTestInformation()
         setTargetFile(targetFile);
         setTargetName(targetName);
         setWorkingDirectory(workDir);
+        setBuildDirectory(buildDir);
         setEnvironment(env);
         setProject(project);
         setGuessedConfiguration(guessedRunConfiguration);
@@ -228,6 +240,11 @@ void TestConfiguration::setWorkingDirectory(const QString &workingDirectory)
     m_workingDir = workingDirectory;
 }
 
+void TestConfiguration::setBuildDirectory(const QString &buildDirectory)
+{
+    m_buildDir = buildDirectory;
+}
+
 void TestConfiguration::setDisplayName(const QString &displayName)
 {
     m_displayName = displayName;
diff --git a/src/plugins/autotest/testconfiguration.h b/src/plugins/autotest/testconfiguration.h
index 632ce69b720eb0b636216ea7741be7a6787613c3..6e9cc8fc345136ac4660b3e011495da18c76c227 100644
--- a/src/plugins/autotest/testconfiguration.h
+++ b/src/plugins/autotest/testconfiguration.h
@@ -56,6 +56,7 @@ public:
     void setTargetName(const QString &targetName);
     void setProFile(const QString &proFile);
     void setWorkingDirectory(const QString &workingDirectory);
+    void setBuildDirectory(const QString &buildDirectory);
     void setDisplayName(const QString &displayName);
     void setEnvironment(const Utils::Environment &env);
     void setProject(ProjectExplorer::Project *project);
@@ -70,6 +71,7 @@ public:
     QString targetFile() const { return m_targetFile; }
     QString targetName() const { return m_targetName; }
     QString workingDirectory() const { return m_workingDir; }
+    QString buildDirectory() const { return m_buildDir; }
     QString displayName() const { return m_displayName; }
     Utils::Environment environment() const { return m_environment; }
     ProjectExplorer::Project *project() const { return m_project.data(); }
@@ -87,6 +89,7 @@ private:
     QString m_targetFile;
     QString m_targetName;
     QString m_workingDir;
+    QString m_buildDir;
     QString m_displayName;
     Utils::Environment m_environment;
     QPointer<ProjectExplorer::Project> m_project;
diff --git a/src/plugins/autotest/testoutputreader.cpp b/src/plugins/autotest/testoutputreader.cpp
index 42d0ea5b5558269618b2071dcd5c54118d263702..2790d19147da514d2d0ed0a7b2ca6889cb7a5ef7 100644
--- a/src/plugins/autotest/testoutputreader.cpp
+++ b/src/plugins/autotest/testoutputreader.cpp
@@ -57,14 +57,8 @@ static QString decode(const QString& original)
     return result;
 }
 
-static QString constructSourceFilePath(const QString &path, const QString &filePath,
-                                       const QString &app)
+static QString constructSourceFilePath(const QString &path, const QString &filePath)
 {
-    if (Utils::HostOsInfo::isMacHost() && !app.isEmpty()) {
-        const QString fileName(QFileInfo(app).fileName());
-        return QFileInfo(path.left(path.lastIndexOf(fileName + QLatin1String(".app"))), filePath)
-                   .canonicalFilePath();
-    }
     return QFileInfo(path, filePath).canonicalFilePath();
 }
 
@@ -137,16 +131,17 @@ static QString constructBenchmarkInformation(const QString &metric, double value
 }
 
 TestOutputReader::TestOutputReader(QFutureInterface<TestResult *> futureInterface,
-                                   QProcess *testApplication)
+                                   QProcess *testApplication, const QString &buildDirectory)
     : m_futureInterface(futureInterface)
     , m_testApplication(testApplication)
+    , m_buildDir(buildDirectory)
 {
     connect(m_testApplication, &QProcess::readyRead, this, &TestOutputReader::processOutput);
 }
 
 QtTestOutputReader::QtTestOutputReader(QFutureInterface<TestResult *> futureInterface,
-                                       QProcess *testApplication)
-    : TestOutputReader(futureInterface, testApplication)
+                                       QProcess *testApplication, const QString &buildDirectory)
+    : TestOutputReader(futureInterface, testApplication, buildDirectory)
 {
 }
 
@@ -207,9 +202,7 @@ void QtTestOutputReader::processOutput()
                                 attributes.value(QStringLiteral("type")).toString());
                     m_file = decode(attributes.value(QStringLiteral("file")).toString());
                     if (!m_file.isEmpty()) {
-                        const QString base = QFileInfo(m_testApplication->program()).absolutePath();
-                        m_file = constructSourceFilePath(base, m_file,
-                                                       m_testApplication->program());
+                        m_file = constructSourceFilePath(m_buildDir, m_file);
                     }
                     m_lineNumber = attributes.value(QStringLiteral("line")).toInt();
                 } else if (currentTag == QStringLiteral("BenchmarkResult")) {
@@ -306,8 +299,8 @@ void QtTestOutputReader::processOutput()
 }
 
 GTestOutputReader::GTestOutputReader(QFutureInterface<TestResult *> futureInterface,
-                                     QProcess *testApplication)
-    : TestOutputReader(futureInterface, testApplication)
+                                     QProcess *testApplication, const QString &buildDirectory)
+    : TestOutputReader(futureInterface, testApplication, buildDirectory)
 {
 }
 
@@ -403,11 +396,9 @@ void GTestOutputReader::processOutput()
             m_description.chop(1);
             testResult->setDescription(m_description);
 
-            const QString base = QFileInfo(m_testApplication->program()).absolutePath();
             foreach (const QString &output, m_description.split(QLatin1Char('\n'))) {
                 if (failureLocation.exactMatch(output)) {
-                    QString file = constructSourceFilePath(base, failureLocation.cap(1),
-                                                           m_testApplication->program());
+                    QString file = constructSourceFilePath(m_buildDir, failureLocation.cap(1));
                     if (file.isEmpty())
                         continue;
                     testResult->setFileName(file);
diff --git a/src/plugins/autotest/testoutputreader.h b/src/plugins/autotest/testoutputreader.h
index 9a50e6055735b8b1e0b5a1a8e20597215f8f327a..44a973145c9a03841da83526127d0339e2b69579 100644
--- a/src/plugins/autotest/testoutputreader.h
+++ b/src/plugins/autotest/testoutputreader.h
@@ -45,19 +45,20 @@ class TestOutputReader : public QObject
     Q_OBJECT
 public:
     TestOutputReader(QFutureInterface<TestResult *> futureInterface,
-                     QProcess *testApplication);
+                     QProcess *testApplication, const QString &buildDirectory);
 
 protected:
     virtual void processOutput() = 0;
     QFutureInterface<TestResult *> m_futureInterface;
     QProcess *m_testApplication;  // not owned
+    QString m_buildDir;
 };
 
 class QtTestOutputReader : public TestOutputReader
 {
 public:
     QtTestOutputReader(QFutureInterface<TestResult *> futureInterface,
-                       QProcess *testApplication);
+                       QProcess *testApplication, const QString &buildDirectory);
 
 protected:
     void processOutput() override;
@@ -89,7 +90,7 @@ class GTestOutputReader : public TestOutputReader
 {
 public:
     GTestOutputReader(QFutureInterface<TestResult *> futureInterface,
-                      QProcess *testApplication);
+                      QProcess *testApplication, const QString &buildDirectory);
 
 protected:
     void processOutput() override;
diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp
index 4914d6d26c9fbdadd596fa0b73be795546307b1e..daab98068bc9ba107a50e34ba9725e988860b0ec 100644
--- a/src/plugins/autotest/testrunner.cpp
+++ b/src/plugins/autotest/testrunner.cpp
@@ -145,10 +145,12 @@ static void performTestRun(QFutureInterface<TestResult *> &futureInterface,
         QScopedPointer<TestOutputReader> outputReader;
         switch (testConfiguration->testType()) {
         case TestTypeQt:
-            outputReader.reset(new QtTestOutputReader(futureInterface, &testProcess));
+            outputReader.reset(new QtTestOutputReader(futureInterface, &testProcess,
+                                                      testConfiguration->buildDirectory()));
             break;
         case TestTypeGTest:
-            outputReader.reset(new GTestOutputReader(futureInterface, &testProcess));
+            outputReader.reset(new GTestOutputReader(futureInterface, &testProcess,
+                                                     testConfiguration->buildDirectory()));
             break;
         }
         if (futureInterface.isCanceled())