diff --git a/composer.lock b/composer.lock
index 6622a70a91..241587ce27 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4237,6 +4237,43 @@
             "description": "Symfony PHPUnit Bridge",
             "homepage": "https://symfony.com",
             "time": "2017-04-12T14:13:17+00:00"
+        },
+        {
+            "name": "webflo/drupal-finder",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/webflo/drupal-finder.git",
+                "reference": "3216448cc347bc77127fa3bf6497ba9b3c296e9c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/3216448cc347bc77127fa3bf6497ba9b3c296e9c",
+                "reference": "3216448cc347bc77127fa3bf6497ba9b3c296e9c",
+                "shasum": ""
+            },
+            "require-dev": {
+                "mikey179/vfsstream": "^1.6",
+                "phpunit/phpunit": "^4.8"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "src/DrupalFinder.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "GPL-2.0+"
+            ],
+            "authors": [
+                {
+                    "name": "Florian Weber",
+                    "email": "florian@webflo.org"
+                }
+            ],
+            "description": "Helper class to locate a Drupal installation from a given path.",
+            "time": "2017-08-08T08:31:26+00:00"
         }
     ],
     "aliases": [],
diff --git a/core/composer.json b/core/composer.json
index bda527f99d..5ca03087f1 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -47,7 +47,8 @@
         "phpunit/phpunit": ">=4.8.35 <5",
         "phpspec/prophecy": "^1.4",
         "symfony/css-selector": "~3.2.8",
-        "symfony/phpunit-bridge": "~3.2.8"
+        "symfony/phpunit-bridge": "~3.2.8",
+        "webflo/drupal-finder": "^1.0.0"
     },
     "replace": {
         "drupal/action": "self.version",
diff --git a/core/tests/Drupal/Tests/ComposerIntegrationTest.php b/core/tests/Drupal/Tests/ComposerIntegrationTest.php
index 511fd529ca..a7a758a95c 100644
--- a/core/tests/Drupal/Tests/ComposerIntegrationTest.php
+++ b/core/tests/Drupal/Tests/ComposerIntegrationTest.php
@@ -5,6 +5,13 @@
 /**
  * Tests Composer integration.
  *
+ * Currently, Drupal requires composer.json files to be in specific places so
+ * that we can test their validity and integrity. This test could fail if the
+ * shipped Drupal 8 file system is modified.
+ *
+ * You can run tests from PHPUnit with --exclude-group Composer in order to
+ * avoid these test fails.
+ *
  * @group Composer
  */
 class ComposerIntegrationTest extends UnitTestCase {
@@ -35,56 +42,22 @@ protected function getErrorMessages() {
   }
 
   /**
-   * Gets the paths to the folders that contain the Composer integration.
-   *
-   * @return string[]
-   *   The paths.
-   */
-  protected function getPaths() {
-    return [
-      $this->root,
-      $this->root . '/core',
-      $this->root . '/core/lib/Drupal/Component/Annotation',
-      $this->root . '/core/lib/Drupal/Component/Assertion',
-      $this->root . '/core/lib/Drupal/Component/Bridge',
-      $this->root . '/core/lib/Drupal/Component/Datetime',
-      $this->root . '/core/lib/Drupal/Component/DependencyInjection',
-      $this->root . '/core/lib/Drupal/Component/Diff',
-      $this->root . '/core/lib/Drupal/Component/Discovery',
-      $this->root . '/core/lib/Drupal/Component/EventDispatcher',
-      $this->root . '/core/lib/Drupal/Component/FileCache',
-      $this->root . '/core/lib/Drupal/Component/FileSystem',
-      $this->root . '/core/lib/Drupal/Component/Gettext',
-      $this->root . '/core/lib/Drupal/Component/Graph',
-      $this->root . '/core/lib/Drupal/Component/HttpFoundation',
-      $this->root . '/core/lib/Drupal/Component/PhpStorage',
-      $this->root . '/core/lib/Drupal/Component/Plugin',
-      $this->root . '/core/lib/Drupal/Component/ProxyBuilder',
-      $this->root . '/core/lib/Drupal/Component/Render',
-      $this->root . '/core/lib/Drupal/Component/Serialization',
-      $this->root . '/core/lib/Drupal/Component/Transliteration',
-      $this->root . '/core/lib/Drupal/Component/Utility',
-      $this->root . '/core/lib/Drupal/Component/Uuid',
-    ];
-  }
-
-  /**
    * Tests composer.json.
+   *
+   * @dataProvider providerTestComposerJson
    */
-  public function testComposerJson() {
-    foreach ($this->getPaths() as $path) {
-      $json = file_get_contents($path . '/composer.json');
-      $result = json_decode($json);
-      $this->assertNotNull($result, $this->getErrorMessages()[json_last_error()]);
-    }
+  public function testComposerJson($path) {
+    $json = file_get_contents($path);
+    $result = json_decode($json);
+    $this->assertNotNull($result, $this->getErrorMessages()[json_last_error()]);
   }
 
   /**
    * Tests composer.lock content-hash.
    */
   public function testComposerLockHash() {
-    $content_hash = self::getContentHash(file_get_contents($this->root . '/composer.json'));
-    $lock = json_decode(file_get_contents($this->root . '/composer.lock'), TRUE);
+    $content_hash = self::getContentHash(file_get_contents($this->composerRoot . '/composer.json'));
+    $lock = json_decode(file_get_contents($this->composerRoot . '/composer.lock'), TRUE);
     $this->assertSame($content_hash, $lock['content-hash']);
   }
 
@@ -120,9 +93,12 @@ public function testComposerTilde($path) {
    * @return array
    */
   public function providerTestComposerJson() {
-    $root = realpath(__DIR__ . '/../../../../');
-    $tests = [[$root . '/composer.json']];
-    $directory = new \RecursiveDirectoryIterator($root . '/core');
+    // Data provider functions are run before setUp(), so we have to determine
+    // DRUPAL_ROOT here.
+    $this->locateRoot();
+
+    $tests = [[$this->composerRoot . '/composer.json']];
+    $directory = new \RecursiveDirectoryIterator($this->root . '/core');
     $iterator = new \RecursiveIteratorIterator($directory);
     /** @var \SplFileInfo $file */
     foreach ($iterator as $file) {
diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php
index 8aaeb85743..f8eeca4446 100644
--- a/core/tests/Drupal/Tests/UnitTestCase.php
+++ b/core/tests/Drupal/Tests/UnitTestCase.php
@@ -8,6 +8,7 @@
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
+use DrupalFinder\DrupalFinder;
 use PHPUnit\Framework\TestCase;
 
 
@@ -33,6 +34,20 @@
   protected $root;
 
   /**
+   * The composer root.
+   *
+   * @var string
+   */
+  protected $composerRoot;
+
+  /**
+   * The DrupalFinder.
+   *
+   * @var \DrupalFinder\DrupalFinder
+   */
+  private $drupalFinder;
+
+  /**
    * {@inheritdoc}
    */
   protected function setUp() {
@@ -46,8 +61,38 @@ protected function setUp() {
     FileCacheFactory::setConfiguration([FileCacheFactory::DISABLE_CACHE => TRUE]);
     // Ensure that FileCacheFactory has a prefix.
     FileCacheFactory::setPrefix('prefix');
+    // Find the app and composer root.
+    $this->locateRoot();
+  }
+
+  /**
+   * Finds the app and composer root for the project if they are not found yet.
+   */
+  public function locateRoot() {
+    if ($this->root === NULL || $this->composerRoot === NULL) {
+      $this->root = dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__)), 2);
+      // Composer root is the same as the app root by default.
+      $this->composerRoot = $this->root;
+
+      // Find the real app and composer root with drupalFinder.
+      if ($this->drupalFinder()->locateRoot($this->root)) {
+        $this->root = $this->drupalFinder()->getDrupalRoot();
+        $this->composerRoot = $this->drupalFinder()->getComposerRoot();
+      }
+    }
+  }
+
+  /**
+   * Creates new drupalFinder instance if it does not exists yet.
+   *
+   * @return \DrupalFinder\DrupalFinder
+   */
+  public function drupalFinder() {
+    if ($this->drupalFinder === NULL) {
+      $this->drupalFinder = new DrupalFinder();
+    }
 
-    $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
+    return $this->drupalFinder;
   }
 
   /**
