diff --git a/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php b/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php
index f53309b..f149b7f 100644
--- a/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php
+++ b/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php
@@ -11,7 +11,7 @@
 /**
  * Defines a base class for Views kernel testing.
  */
-class ViewsKernelTestBase extends KernelTestBase {
+abstract class ViewsKernelTestBase extends KernelTestBase {
 
   use ViewResultAssertionTrait;
 
diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist
index 2b45c64..951bd55 100644
--- a/core/phpunit.xml.dist
+++ b/core/phpunit.xml.dist
@@ -28,48 +28,16 @@
   </php>
   <testsuites>
     <testsuite name="unit">
-      <directory>./tests/Drupal/Tests</directory>
-      <directory>./modules/*/tests/src/Unit</directory>
-      <directory>../modules/*/tests/src/Unit</directory>
-      <directory>../profiles/*/tests/src/Unit</directory>
-      <directory>../sites/*/modules/*/tests/src/Unit</directory>
-      <!-- Exclude Composer's vendor directory so we don't run tests there. -->
-      <exclude>./vendor</exclude>
-      <!-- Exclude Drush tests. -->
-      <exclude>./drush/tests</exclude>
+      <file>./tests/TestSuites/UnitTestSuite.php</file>
     </testsuite>
     <testsuite name="kernel">
-      <directory>./tests/Drupal/KernelTests</directory>
-      <directory>./modules/*/tests/src/Kernel</directory>
-      <directory>../modules/*/tests/src/Kernel</directory>
-      <directory>../profiles/*/tests/src/Kernel</directory>
-      <directory>../sites/*/modules/*/tests/src/Kernel</directory>
-      <!-- Exclude Composer's vendor directory so we don't run tests there. -->
-      <exclude>./vendor</exclude>
-      <!-- Exclude Drush tests. -->
-      <exclude>./drush/tests</exclude>
+      <file>./tests/TestSuites/KernelTestSuite.php</file>
     </testsuite>
     <testsuite name="functional">
-      <directory>./tests/Drupal/FunctionalTests</directory>
-      <directory>./modules/*/tests/src/Functional</directory>
-      <directory>../modules/*/tests/src/Functional</directory>
-      <directory>../profiles/*/tests/src/Functional</directory>
-      <directory>../sites/*/modules/*/tests/src/Functional</directory>
-      <!-- Exclude Composer's vendor directory so we don't run tests there. -->
-      <exclude>./vendor</exclude>
-      <!-- Exclude Drush tests. -->
-      <exclude>./drush/tests</exclude>
+      <file>./tests/TestSuites/FunctionalTestSuite.php</file>
     </testsuite>
     <testsuite name="functional-javascript">
-      <directory>./tests/Drupal/FunctionalJavascriptTests</directory>
-      <directory>./modules/*/tests/src/FunctionalJavascript</directory>
-      <directory>../modules/*/tests/src/FunctionalJavascript</directory>
-      <directory>../profiles/*/tests/src/FunctionalJavascript</directory>
-      <directory>../sites/*/modules/*/tests/src/FunctionalJavascript</directory>
-      <!-- Exclude Composer's vendor directory so we don't run tests there. -->
-      <exclude>./vendor</exclude>
-      <!-- Exclude Drush tests. -->
-      <exclude>./drush/tests</exclude>
+      <file>./tests/TestSuites/FunctionalJavascriptTestSuite.php</file>
     </testsuite>
   </testsuites>
   <listeners>
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
index 834d0a4..7c5e855 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
@@ -22,7 +22,7 @@
 /**
  * Base class for the actual unit tests testing \Drupal\Core\Render\Renderer.
  */
-class RendererTestBase extends UnitTestCase {
+abstract class RendererTestBase extends UnitTestCase {
 
   /**
    * The tested renderer.
diff --git a/core/tests/TestSuites/FunctionalJavascriptTestSuite.php b/core/tests/TestSuites/FunctionalJavascriptTestSuite.php
new file mode 100644
index 0000000..79ca468
--- /dev/null
+++ b/core/tests/TestSuites/FunctionalJavascriptTestSuite.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\Tests\TestSuites;
+
+require_once __DIR__ . '/TestSuiteBase.php';
+
+/**
+ * Discovers tests for the unit test suite.
+ */
+class FunctionalJavascriptTestSuite extends TestSuiteBase {
+
+  /**
+   * Factory method which loads up a suite with all functional javascript tests.
+   *
+   * @return static
+   *   The test suite.
+   */
+  public static function suite() {
+    $root = dirname(dirname(dirname(__DIR__)));
+
+    $suite = new static('functional-javascript');
+    $suite->addTestsBySuiteNamespace($root, 'FunctionalJavascript');
+
+    return $suite;
+  }
+
+}
diff --git a/core/tests/TestSuites/FunctionalTestSuite.php b/core/tests/TestSuites/FunctionalTestSuite.php
new file mode 100644
index 0000000..7e5f264
--- /dev/null
+++ b/core/tests/TestSuites/FunctionalTestSuite.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\Tests\TestSuites;
+
+require_once __DIR__ . '/TestSuiteBase.php';
+
+/**
+ * Discovers tests for the unit test suite.
+ */
+class FunctionalTestSuite extends TestSuiteBase {
+
+  /**
+   * Factory method which loads up a suite with all unit tests.
+   *
+   * @return static
+   *   The test suite.
+   */
+  public static function suite() {
+    $root = dirname(dirname(dirname(__DIR__)));
+
+    $suite = new static('functional');
+    $suite->addTestsBySuiteNamespace($root, 'Functional');
+
+    return $suite;
+  }
+
+}
diff --git a/core/tests/TestSuites/KernelTestSuite.php b/core/tests/TestSuites/KernelTestSuite.php
new file mode 100644
index 0000000..5eb28cc
--- /dev/null
+++ b/core/tests/TestSuites/KernelTestSuite.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\Tests\TestSuites;
+
+require_once __DIR__ . '/TestSuiteBase.php';
+
+/**
+ * Discovers tests for the kernel test suite.
+ */
+class KernelTestSuite extends TestSuiteBase {
+
+  /**
+   * Factory method which loads up a suite with all unit tests.
+   *
+   * @return static
+   *   The test suite.
+   */
+  public static function suite() {
+    $root = dirname(dirname(dirname(__DIR__)));
+
+    $suite = new static('kernel');
+    $suite->addTestsBySuiteNamespace($root, 'Kernel');
+
+    return $suite;
+  }
+
+}
diff --git a/core/tests/TestSuites/TestSuiteBase.php b/core/tests/TestSuites/TestSuiteBase.php
new file mode 100644
index 0000000..0e87552
--- /dev/null
+++ b/core/tests/TestSuites/TestSuiteBase.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Drupal\Tests\TestSuites;
+use Drupal\simpletest\TestDiscovery;
+
+/**
+ * Base class for Drupal test suites.
+ */
+class TestSuiteBase extends \PHPUnit_Framework_TestSuite {
+
+  /**
+   * Finds extensions in a Drupal installation.
+   *
+   * An extension is defined as a directory with an *.info.yml file in it.
+   *
+   * @return string[]
+   *   Associative array of extension paths, with extension name as keys.
+   */
+  public static function findExtensionDirectories() {
+    $extension_roots = \drupal_phpunit_contrib_extension_directory_roots();
+
+    $extension_directories = array_map('drupal_phpunit_find_extension_directories', $extension_roots);
+    return array_reduce($extension_directories, 'array_merge', array());
+  }
+
+  /**
+   * Find and add tests to the suite for core and any extensions.
+   *
+   * @param string $root
+   *   Path to the root of the Drupal installation.
+   * @param string $suite_namespace
+   *   SubNamespace used to separate test suite.
+   */
+  protected function addTestsBySuiteNamespace($root, $suite_namespace) {
+    // Core's tests are in the namespace Drupal\${suite_namespace}Tests\ and are
+    // always inside of core/tests/Drupal/${suite_namespace}Tests. The exception
+    // this is Unit tests for historical reasons.
+    if ($suite_namespace == 'Unit') {
+      $this->addTestFiles(TestDiscovery::scanDirectory("Drupal\\Tests\\", "$root/core/tests/Drupal/Tests"));
+    }
+    else {
+      $this->addTestFiles(TestDiscovery::scanDirectory("Drupal\\${suite_namespace}Tests\\", "$root/core/tests/Drupal/${suite_namespace}Tests"));
+    }
+
+    // Extensions' will always be in the namespace
+    // Drupal\Tests\$extension_name\$suite_namespace\ and be in the
+    // $extension_path/tests/src/$suite_namespace directory. Not all extensions
+    // will have tests.
+    foreach (static::findExtensionDirectories() as $extension_name => $dir) {
+      $test_path = "$dir/tests/src/$suite_namespace";
+      if (is_dir($test_path)) {
+        $this->addTestFiles(TestDiscovery::scanDirectory("Drupal\\Tests\\$extension_name\\$suite_namespace\\", $test_path));
+      }
+    }
+  }
+
+}
diff --git a/core/tests/TestSuites/UnitTestSuite.php b/core/tests/TestSuites/UnitTestSuite.php
new file mode 100644
index 0000000..b05d455
--- /dev/null
+++ b/core/tests/TestSuites/UnitTestSuite.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\Tests\TestSuites;
+
+require_once __DIR__ . '/TestSuiteBase.php';
+
+/**
+ * Discovers tests for the unit test suite.
+ */
+class UnitTestSuite extends TestSuiteBase {
+
+  /**
+   * Factory method which loads up a suite with all unit tests.
+   *
+   * @return static
+   *   The test suite.
+   */
+  public static function suite() {
+    $root = dirname(dirname(dirname(__DIR__)));
+
+    $suite = new static('unit');
+    $suite->addTestsBySuiteNamespace($root, 'Unit');
+
+    return $suite;
+  }
+
+}
