diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index d8b653e..38737db 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -144,7 +144,8 @@ function simpletest_run_tests($test_list) {
 
   // Get the info for the first test being run.
   $first_test = reset($test_list);
-  $info = TestDiscovery::getTestInfo($first_test);
+  $test_discovery = \Drupal::service('test_discovery');
+  $info = $test_discovery->getTestInfo($first_test);
 
   $batch = array(
     'title' => t('Running tests'),
@@ -355,7 +356,8 @@ function _simpletest_batch_operation($test_list_init, $test_id, &$context) {
   $test = new $test_class($test_id);
   $test->run();
   $size = count($test_list);
-  $info = TestDiscovery::getTestInfo($test_class);
+  $test_discovery = \Drupal::service('test_discovery');
+  $info = $test_discovery->getTestInfo($test_class);
 
   \Drupal::moduleHandler()->invokeAll('test_finished', array($test->results));
 
diff --git a/core/modules/simpletest/src/Exception/TestInWrongNamespaceException.php b/core/modules/simpletest/src/Exception/TestInWrongNamespaceException.php
new file mode 100644
index 0000000..60f1a41
--- /dev/null
+++ b/core/modules/simpletest/src/Exception/TestInWrongNamespaceException.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace Drupal\simpletest\Exception;
+
+/**
+ * Exception thrown when a test class' namespace does not match a test type.
+ */
+class TestInWrongNamespaceException extends \LogicException {
+}
diff --git a/core/modules/simpletest/src/Form/SimpletestResultsForm.php b/core/modules/simpletest/src/Form/SimpletestResultsForm.php
index d2a84d6..cc7a3b3 100644
--- a/core/modules/simpletest/src/Form/SimpletestResultsForm.php
+++ b/core/modules/simpletest/src/Form/SimpletestResultsForm.php
@@ -279,7 +279,8 @@ public static function addResultForm(array &$form, array $results) {
       '#debug' => 0,
     );
 
-    \Drupal::service('test_discovery')->registerTestNamespaces();
+    $test_discovery = \Drupal::service('test_discovery');
+    $test_discovery->registerTestNamespaces();
 
     // Cycle through each test group.
     $header = array(
@@ -293,7 +294,7 @@ public static function addResultForm(array &$form, array $results) {
     $form['result']['results'] = array();
     foreach ($test_results as $group => $assertions) {
       // Create group details with summary information.
-      $info = TestDiscovery::getTestInfo($group);
+      $info = TestDiscovery::$test_discovery->getTestInfo($group);
       $form['result']['results'][$group] = array(
         '#type' => 'details',
         '#title' => $info['name'],
diff --git a/core/modules/simpletest/src/TestDiscovery.php b/core/modules/simpletest/src/TestDiscovery.php
index d3a72dd..f05d4ae 100644
--- a/core/modules/simpletest/src/TestDiscovery.php
+++ b/core/modules/simpletest/src/TestDiscovery.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Extension\ExtensionDiscovery;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\simpletest\Exception\MissingGroupException;
+use Drupal\simpletest\Exception\TestInWrongNamespaceException;
 use PHPUnit_Util_Test;
 
 /**
@@ -81,11 +82,13 @@ public function __construct($root, $class_loader, ModuleHandlerInterface $module
   }
 
   /**
-   * Registers test namespaces of all available extensions.
+   * Registers the test namespaces of all available extensions.
    *
    * @return array
    *   An associative array whose keys are PSR-4 namespace prefixes and whose
    *   values are directory names.
+   *
+   * @see https://www.drupal.org/node/2116043
    */
   public function registerTestNamespaces() {
     if (isset($this->testNamespaces)) {
@@ -107,18 +110,16 @@ public function registerTestNamespaces() {
 
       $base_path = $this->root . '/' . $extension->getPath();
 
-      // Add namespace of disabled/uninstalled extensions.
+      // Register namespace of disabled/uninstalled extensions on the
+      // classloader.
       if (!isset($existing["Drupal\\$name\\"])) {
         $this->classLoader->addPsr4("Drupal\\$name\\", "$base_path/src");
       }
       // Add Simpletest test namespace.
       $this->testNamespaces["Drupal\\$name\\Tests\\"][] = "$base_path/src/Tests";
 
-      // Add PHPUnit test namespaces.
-      $this->testNamespaces["Drupal\\Tests\\$name\\Unit\\"][] = "$base_path/tests/src/Unit";
-      $this->testNamespaces["Drupal\\Tests\\$name\\Kernel\\"][] = "$base_path/tests/src/Kernel";
-      $this->testNamespaces["Drupal\\Tests\\$name\\Functional\\"][] = "$base_path/tests/src/Functional";
-      $this->testNamespaces["Drupal\\Tests\\$name\\FunctionalJavascript\\"][] = "$base_path/tests/src/FunctionalJavascript";
+      // Add PHPUnit-based test namespaces.
+      $this->testNamespaces["Drupal\\Tests\\$name\\"][] = "$base_path/tests/src";
     }
 
     foreach ($this->testNamespaces as $prefix => $paths) {
@@ -174,7 +175,7 @@ public function getTestClasses($extension = NULL, array $types = []) {
       $finder = MockFileFinder::create($pathname);
       $parser = new StaticReflectionParser($classname, $finder, TRUE);
       try {
-        $info = static::getTestInfo($classname, $parser->getDocComment());
+        $info = $this->getTestInfo($classname, $parser->getDocComment());
       }
       catch (MissingGroupException $e) {
         // If the class name ends in Test and is not a migrate table dump.
@@ -258,7 +259,7 @@ public function findAllClassFiles($extension = NULL) {
    * @param string $namespace_prefix
    *   The namespace prefix to use for discovered classes. Must contain a
    *   trailing namespace separator (backslash).
-   *   For example: 'Drupal\\node\\Tests\\'
+   *   For example: 'Drupal\\Tests\\node\\'
    * @param string $path
    *   The directory path to scan.
    *   For example: '/path/to/drupal/core/modules/node/tests/src'
@@ -323,7 +324,7 @@ public static function scanDirectory($namespace_prefix, $path) {
    * @throws \Drupal\simpletest\Exception\MissingGroupException
    *   If the class does not have a @group annotation.
    */
-  public static function getTestInfo($classname, $doc_comment = NULL) {
+  public function getTestInfo($classname, $doc_comment = NULL) {
     if (!$doc_comment) {
       $reflection = new \ReflectionClass($classname);
       $doc_comment = $reflection->getDocComment();
@@ -351,12 +352,10 @@ public static function getTestInfo($classname, $doc_comment = NULL) {
       throw new MissingGroupException(sprintf('Missing @group annotation in %s', $classname));
     }
     $info['group'] = $annotations['group'];
-    // Put PHPUnit test suites into their own custom groups.
-    if ($testsuite = static::getPhpunitTestSuite($classname)) {
-      $info['type'] = 'PHPUnit-' . $testsuite;
-    }
-    else {
-      $info['type'] = 'Simpletest';
+
+    // Set the type to the test suite.
+    if ($testsuite = $this->getTestSuite($classname)) {
+      $info['type'] = $testsuite;
     }
 
     if (!empty($annotations['coversDefaultClass'])) {
@@ -435,17 +434,70 @@ public static function parseTestClassAnnotations(\ReflectionClass $class) {
     }
     return $annotations;
   }
+  
+  /**
+   * Check if test class is part of core.
+   *
+   * @param string $classname
+   *   class name of a test.
+   *
+   * @return bool
+   *   TRUE if a class file was found under core/
+   */
+  public function isCoreClass($classname) {
+    $path = $this->classLoader->findFile($classname);
+    $base_path = DRUPAL_ROOT . "/core/";
+    if ($path) {
+      return strpos($base_path, $path) === 0;
+    }
+    return FALSE;
+  }
+
+  /**
+   * Determines the test suite for a given class name, based on class name.
+   *
+   * A test suite is any special case for running the given test class. This
+   * includes both PHPUnit-* variants and Simpletest.
+   *
+   * @param string $classname
+   *   The class name.
+   *
+   * @return string
+   *   The test suite. This could be any of the PHPUnit-* variants or
+   *   Simpletest.
+   *
+   * @throws \Drupal\simpletest\Exception\TestInWrongNamespaceException
+   *   Thrown when the test class' namespace does not reflect a known test
+   *   suite.
+   */
+  public function getTestSuite($classname) {
+    if ($suite = $this->getPhpunitTestSuite($classname)) {
+      return 'PHPUnit-' . $suite;
+    }
+    else {
+      // Looking for '\Drupal\module\Tests\AnyTestName\AnyLength' with or
+      // without leading '\'.
+      if (preg_match('/\\\\?Drupal\\\\[a-z]\\w*\\\\Tests\\\\[a-zA-Z\\\\]*/', $classname) == 1) {
+        return 'Simpletest';
+      }
+    }
+    throw new TestInWrongNamespaceException(' -- Test class ' . $classname . ' cannot be assigned to a test suite. See https://www.drupal.org/phpunit. -- ');
+  }
 
   /**
    * Determines the phpunit testsuite for a given classname.
    *
+   * The current PHPUnit test suites are: Unit, Kernel, Functional, and
+   * FunctionalJavascript.
+   *
    * @param string $classname
    *   The test classname.
    *
    * @return string|false
-   *   The testsuite name or FALSE if its not a phpunit test.
+   *   The testsuite name or FALSE if the class name does not reflect one of
+   *   Unit, Kernel, Functional, or FunctionalJavascript.
    */
-  public static function getPhpunitTestSuite($classname) {
+  public function getPhpunitTestSuite($classname) {
     if (preg_match('/Drupal\\\\Tests\\\\Core\\\\(\w+)/', $classname, $matches)) {
       return 'Unit';
     }
@@ -453,15 +505,26 @@ public static function getPhpunitTestSuite($classname) {
       return 'Unit';
     }
     // Module tests.
+    $suites = ['Unit', 'Kernel', 'Functional', 'FunctionalJavascript'];
     if (preg_match('/Drupal\\\\Tests\\\\(\w+)\\\\(\w+)/', $classname, $matches)) {
-      return $matches[2];
+      if (in_array($matches[2], $suites)) {
+        return $matches[2];
+      }
+      else {
+        // We allow non-standard test suites in Contrib.
+        if (!$this->isCoreClass($classname)) {
+          return 'Unclassified';
+        }
+      }
     }
     // Core tests.
     elseif (preg_match('/Drupal\\\\(\w*)Tests\\\\/', $classname, $matches)) {
       if ($matches[1] == '') {
         return 'Unit';
       }
-      return $matches[1];
+      if (in_array($matches[1], $suites)) {
+        return $matches[1];
+      }
     }
     return FALSE;
   }
diff --git a/core/modules/simpletest/tests/src/Kernel/TestDiscoveryTest.php b/core/modules/simpletest/tests/src/Kernel/TestDiscoveryTest.php
new file mode 100644
index 0000000..345a1cf
--- /dev/null
+++ b/core/modules/simpletest/tests/src/Kernel/TestDiscoveryTest.php
@@ -0,0 +1,313 @@
+<?php
+
+namespace Drupal\Tests\simpletest\Kernel;
+
+use Composer\Autoload\ClassLoader;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\simpletest\Exception\TestInWrongNamespaceException;
+use Drupal\simpletest\TestDiscovery;
+use Drupal\KernelTests\KernelTestBase;
+use org\bovigo\vfs\vfsStream;
+
+/**
+ * Tests the test discovery mechanisms.
+ *
+ * @group simpletest
+ *
+ * @coversDefaultClass Drupal\simpletest\TestDiscovery
+ *
+ * @see \Drupal\Tests\simpletest\Unit\TestInfoParsingTest
+ *
+ * @todo: Change this to a Unit test when ExtensionDiscovery does not require
+ *   services or the kernel.
+ */
+class TestDiscoveryTest extends KernelTestBase {
+
+  /**
+   * Fetch a generic TestDiscovery object.
+   *
+   * A vfsStream file system should be set up before
+   * this function is called.
+   *
+   * @return Drupal\simpletest\TestDiscovery
+   */
+  protected function fetchSimpleTestDiscovery() {
+    $class_loader = new ClassLoader();
+    $module_handler = $this->prophesize(ModuleHandlerInterface::class);
+    $test_discovery = new TestDiscovery('vfs://drupal', $class_loader, $module_handler->reveal());
+    return $test_discovery;
+  }
+
+  /**
+   * Build a fixture file system with a module with tests.
+   */
+  protected function setupVfsWithTestClasses() {
+    vfsStream::setup('drupal');
+
+    $test_file = <<<EOF
+<?php
+
+/**
+ * Test description
+ * @group example
+ */
+class FunctionalExampleTest {}
+EOF;
+
+    vfsStream::create([
+      'modules' => [
+        'test_module' => [
+          'test_module.info.yml' => 'type: module',
+          'tests' => [
+            'src' => [
+              'Functional' => [
+                'FunctionalExampleTest.php' => $test_file,
+                'FunctionalExampleTest2.php' => str_replace(
+                  ['FunctionalExampleTest', '@group example'],
+                  ['FunctionalExampleTest2', '@group example2'],
+                  $test_file
+                ),
+              ],
+              'Kernel' => [
+                'KernelExampleTest3.php' => str_replace(
+                  ['FunctionalExampleTest', '@group example'],
+                  ['KernelExampleTest3', '@group example2'],
+                  $test_file
+                ),
+              ],
+            ],
+          ],
+        ],
+      ],
+    ]);
+  }
+
+  /**
+   * @covers ::registerTestNamespaces
+   */
+  public function testRegisterTestNamespaces() {
+    $this->setupVfsWithTestClasses();
+    $class_loader = new ClassLoader();
+    $module_handler = $this->prophesize(ModuleHandlerInterface::class);
+
+    $test_discovery = new TestDiscovery('vfs://drupal', $class_loader, $module_handler->reveal());
+
+    $discovery_psr4 = $test_discovery->registerTestNamespaces();
+    $classloader_psr4 = $class_loader->getPrefixesPsr4();
+
+    // The module's src/ namespace is not in the test namespace, but is added
+    // to the classloader if the module is not 'enabled'.
+    $src_namespace = 'Drupal\\test_module\\';
+    $this->assertArrayHasKey($src_namespace, $classloader_psr4);
+    $this->assertFalse(isset($discovery_psr4[$src_namespace]));
+
+    $test_namespaces = [
+      'Drupal\\test_module\\Tests\\',
+      'Drupal\\Tests\\test_module\\',
+    ];
+    foreach ($test_namespaces as $test_namespace) {
+      $this->assertArrayHasKey($test_namespace, $discovery_psr4);
+    }
+  }
+
+  /**
+   * @covers ::getTestClasses
+   */
+  public function testGetTestClasses() {
+    $this->setupVfsWithTestClasses();
+
+    $class_loader = new ClassLoader();
+    $module_handler = $this->prophesize(ModuleHandlerInterface::class);
+
+    $test_discovery = new TestDiscovery('vfs://drupal', $class_loader, $module_handler->reveal());
+
+    $classes = $test_discovery->getTestClasses();
+
+    // Groups we expect to find at the top level of the classes response.
+    $groups = [
+      'example',
+      'example2',
+    ];
+    $ungrouped_classes = [];
+    foreach ($groups as $group) {
+      $this->assertArrayHasKey($group, $classes);
+      // Build the array for the next test.
+      $ungrouped_classes = array_merge($ungrouped_classes, $classes[$group]);
+    }
+    // Make sure we got all of the groups.
+    $this->assertEquals(count($groups), count(array_keys($classes)));
+
+    // Class names we expect to find.
+    $expected_classes = [
+      'Drupal\Tests\test_module\Functional\FunctionalExampleTest',
+      'Drupal\Tests\test_module\Functional\FunctionalExampleTest2',
+      'Drupal\Tests\test_module\Kernel\KernelExampleTest3',
+    ];
+    foreach ($expected_classes as $expected_class) {
+      $this->assertArrayHasKey($expected_class, $ungrouped_classes);
+    }
+    // Make sure we got all of the classes.
+    $this->assertEquals(count($expected_classes), count($ungrouped_classes));
+  }
+
+  /**
+   * Build a fixture file system with a module with tests.
+   */
+  protected function setupVfsTestWithWrongNamespace() {
+    vfsStream::setup('drupal');
+
+    $test_file = <<<EOF
+<?php
+
+/**
+ * Test description
+ * @group example
+ */
+class FunctionalExampleTest {}
+EOF;
+
+    vfsStream::create([
+      'modules' => [
+        'test_module' => [
+          'test_module.info.yml' => 'type: module',
+          'tests' => [
+            'src' => [
+              'Unfunctional' => [
+                'FunctionalExampleTest.php' => $test_file,
+              ],
+            ],
+          ],
+        ],
+      ],
+    ]);
+  }
+
+  /**
+   * @covers ::getTestClasses
+   */
+  public function testGetTestClassesWrongNamespace() {
+    $this->setExpectedException(TestInWrongNamespaceException::class);
+    $class_loader = new ClassLoader();
+    $module_handler = $this->prophesize(ModuleHandlerInterface::class);
+    $this->setupVfsTestWithWrongNamespace();
+
+    // We use a standard PHPUnit mock, since we want a test
+    // discovery object that will behave as if it's testing
+    // a core class.
+    $test_discovery = $this->getMockBuilder(TestDiscovery::class)
+      ->setMethods(['isCoreClass'])
+      ->setConstructorArgs(['vfs://drupal', $class_loader, $module_handler->reveal()])
+      ->getMock();
+   
+   $test_discovery
+     ->method('isCoreClass')
+     ->willReturn(TRUE);
+     
+   //$rslt = $test_discovery->inCoreClass('some\class'); 
+
+   $classes = $test_discovery->getTestClasses();
+  }
+
+  /**
+   * @covers ::getPhpunitTestSuite
+   * @dataProvider providerTestGetPhpunitTestSuite
+   */
+  public function testGetPhpunitTestSuite($classname, $expected, $suite) {
+    vfsStream::setup('drupal');
+    $test_discovery = $this->fetchSimpleTestDiscovery();    
+    $this->assertEquals($expected, $test_discovery->getPhpunitTestSuite($classname));
+  }
+
+  /**
+   * @covers ::getTestSuite
+   * @dataProvider providerTestGetPhpunitTestSuite
+   */
+  public function testGetTestSuite($classname, $type, $expected) {
+    vfsStream::setup('drupal');
+    $test_discovery = $this->fetchSimpleTestDiscovery();
+    $this->assertEquals($expected, $test_discovery->getTestSuite($classname));
+  }
+
+  /**
+   * @return array[]
+   *   - Class name.
+   *   - PHPUnit-based test suite, or FALSE.
+   *   - Test suite.
+   */
+  public function providerTestGetPhpunitTestSuite() {
+    $data = [];
+    $data['simpletest-webtest'] = [
+      '\Drupal\rest\Tests\NodeTest',
+      FALSE,
+      'Simpletest',
+    ];
+    $data['simpletest-kerneltest'] = [
+      '\Drupal\hal\Tests\FileNormalizeTest',
+      FALSE,
+      'Simpletest',
+    ];
+    $data['module-unittest'] = [
+      'Drupal\Tests\simpletest\Unit\PhpUnitAutoloaderTest',
+      'Unit',
+      'PHPUnit-Unit',
+    ];
+    $data['module-kerneltest'] = [
+      static::class,
+      'Kernel',
+      'PHPUnit-Kernel',
+    ];
+    $data['module-functionaltest'] = [
+      '\Drupal\Tests\simpletest\Functional\BrowserTestBaseTest',
+      'Functional',
+      'PHPUnit-Functional',
+    ];
+    $data['module-functionaljavascripttest'] = [
+      '\Drupal\Tests\toolbar\FunctionalJavascript\ToolbarIntegrationTest',
+      'FunctionalJavascript',
+      'PHPUnit-FunctionalJavascript'
+    ];
+    $data['core-unittest'] = [
+      '\Drupal\Tests\ComposerIntegrationTest',
+      'Unit',
+      'PHPUnit-Unit',
+    ];
+    $data['core-unittest2'] = [
+      'Drupal\Tests\Core\DrupalTest',
+      'Unit',
+      'PHPUnit-Unit',
+    ];
+    $data['core-kerneltest'] = [
+      '\Drupal\KernelTests\KernelTestBaseTest',
+      'Kernel',
+      'PHPUnit-Kernel',
+    ];
+    $data['core-functionaltest'] = [
+      '\Drupal\FunctionalTests\ExampleTest',
+      'Functional',
+      'PHPUnit-Functional',
+    ];
+    $data['core-functionaljavascripttest'] = [
+      '\Drupal\FunctionalJavascriptTests\ExampleTest',
+      'FunctionalJavascript',
+      'PHPUnit-FunctionalJavascript',
+    ];
+    return $data;
+  }
+
+  /**
+   * @dataProvider provideGetTestSuiteBadSuite
+   */
+  public function testGetTestSuiteBadSuite($classname) {
+    $this->setExpectedException(TestInWrongNamespaceException::class);
+    vfsStream::setup('drupal');
+    $test_discovery = $this->fetchSimpleTestDiscovery();
+    $test_discovery->getTestSuite($classname);
+  }
+
+  public function provideGetTestSuiteBadSuite() {
+    return [
+      ['\Boy\Is\This\Ever\Wrong'],
+    ];
+  }
+
+}
diff --git a/core/modules/simpletest/tests/src/Traits/TestTrait.php b/core/modules/simpletest/tests/src/Traits/TestTrait.php
new file mode 100644
index 0000000..ebd5da7
--- /dev/null
+++ b/core/modules/simpletest/tests/src/Traits/TestTrait.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Drupal\Tests\simpletest\Traits;
+
+/**
+ * Provides a trait declared in the Drupal\Tests namespace.
+ *
+ * We declare the trait here to make sure that traits found in
+ * the Drupal\Tests namespace are visible to our test runner.
+ *
+ * @see Drupal\Tests\simpletest\Unit\TestTraitAccessTest
+ */
+trait TestTrait {
+  /**
+   * Test string for our not very interesting trait.
+   *
+   * @var string
+   */
+  protected $stuff = 'stuff';
+
+  /**
+   * Return a test string to a trait user.
+   *
+   * @return string
+   *   A test string.
+   */
+  protected function getStuff() {
+    return $this->stuff;
+  }
+
+}
diff --git a/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php b/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php
index 9a69d78..7d50298 100644
--- a/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php
+++ b/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\Tests\simpletest\Unit {
 
 use Composer\Autoload\ClassLoader;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Extension\Extension;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\simpletest\TestDiscovery;
@@ -17,15 +18,38 @@
 /**
  * @coversDefaultClass \Drupal\simpletest\TestDiscovery
  * @group simpletest
+ *
+ * @see \Drupal\simpletest\Unit\TestDiscoveryTest
  */
 class TestInfoParsingTest extends UnitTestCase {
+  
+  /**
+   * Test discovery instance.
+   *
+   * @var TestDiscovery
+   */
+  protected $testDiscovery;
+  
+  /**
+   * {{@inheritdoc}}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $container = new ContainerBuilder(); 
+    $class_loader = new ClassLoader();
+    $module_handler = $this->prophesize(ModuleHandlerInterface::class);
+    $test_discovery = new TestDiscovery("./", $class_loader, $module_handler->reveal());
+    $container->set('test_discovery', $test_discovery);
+    $this->testDiscovery = $test_discovery;
+    \Drupal::setContainer($container);
+  }
 
   /**
    * @covers ::getTestInfo
    * @dataProvider infoParserProvider
    */
   public function testTestInfoParser($expected, $classname, $doc_comment = NULL) {
-    $info = TestDiscovery::getTestInfo($classname, $doc_comment);
+    $info = $this->testDiscovery->getTestInfo($classname, $doc_comment);
     $this->assertEquals($expected, $info);
   }
 
@@ -245,7 +269,7 @@ public function testTestInfoParserMissingGroup() {
  * Bulk delete storages and fields, and clean up afterwards.
  */
 EOT;
-    TestDiscovery::getTestInfo($classname, $doc_comment);
+    $this->testDiscovery->getTestInfo($classname, $doc_comment);
   }
 
   /**
@@ -258,7 +282,7 @@ public function testTestInfoParserMissingSummary() {
  * @group field
  */
 EOT;
-    $info = TestDiscovery::getTestInfo($classname, $doc_comment);
+    $info = $this->testDiscovery->getTestInfo($classname, $doc_comment);
     $this->assertEmpty($info['description']);
   }
 
@@ -386,31 +410,6 @@ protected function getExtensions() {
     return $this->extensions;
   }
 
-  /**
-   * @covers ::getPhpunitTestSuite
-   * @dataProvider providerTestGetPhpunitTestSuite
-   */
-  public function testGetPhpunitTestSuite($classname, $expected) {
-    $this->assertEquals($expected, TestDiscovery::getPhpunitTestSuite($classname));
-  }
-
-  public function providerTestGetPhpunitTestSuite() {
-    $data = [];
-    $data['simpletest-webtest'] = ['\Drupal\rest\Tests\NodeTest', FALSE];
-    $data['simpletest-kerneltest'] = ['\Drupal\hal\Tests\FileNormalizeTest', FALSE];
-    $data['module-unittest'] = [static::class, 'Unit'];
-    $data['module-kerneltest'] = ['\Drupal\KernelTests\Core\Theme\TwigMarkupInterfaceTest', 'Kernel'];
-    $data['module-functionaltest'] = ['\Drupal\Tests\simpletest\Functional\BrowserTestBaseTest', 'Functional'];
-    $data['module-functionaljavascripttest'] = ['\Drupal\Tests\toolbar\FunctionalJavascript\ToolbarIntegrationTest', 'FunctionalJavascript'];
-    $data['core-unittest'] = ['\Drupal\Tests\ComposerIntegrationTest', 'Unit'];
-    $data['core-unittest2'] = ['Drupal\Tests\Core\DrupalTest', 'Unit'];
-    $data['core-kerneltest'] = ['\Drupal\KernelTests\KernelTestBaseTest', 'Kernel'];
-    $data['core-functionaltest'] = ['\Drupal\FunctionalTests\ExampleTest', 'Functional'];
-    $data['core-functionaljavascripttest'] = ['\Drupal\FunctionalJavascriptTests\ExampleTest', 'FunctionalJavascript'];
-
-    return $data;
-  }
-
 }
 
 }
diff --git a/core/modules/simpletest/tests/src/Unit/TraitAccessTest.php b/core/modules/simpletest/tests/src/Unit/TraitAccessTest.php
new file mode 100644
index 0000000..0ec450b
--- /dev/null
+++ b/core/modules/simpletest/tests/src/Unit/TraitAccessTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\Tests\simpletest\Unit;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\Tests\simpletest\Traits\TestTrait;
+
+/**
+ * Tests if a PHPUnit test can find a trait under the Drupal\Tests namespace.
+ *
+ * @group simpletest
+ */
+class TraitAccessTest extends UnitTestCase {
+
+  use TestTrait;
+
+  /**
+   * Test if method acquired via the trait is found.
+   */
+  public function testSimpleStuff() {
+    $this->assertSame('stuff', $this->getStuff());
+  }
+
+}
diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh
index df61328..39dc581 100755
--- a/core/scripts/run-tests.sh
+++ b/core/scripts/run-tests.sh
@@ -1065,8 +1065,9 @@ function simpletest_script_get_test_list() {
   // If the test list creation does not automatically limit by test type then
   // we need to do so here.
   if (!$types_processed) {
-    $test_list = array_filter($test_list, function ($test_class) use ($args) {
-      $test_info = TestDiscovery::getTestInfo($test_class);
+    $test_discovery = \Drupal::service('test_discovery');
+    $test_list = array_filter($test_list, function ($test_class) use ($args, $test_discovery) {
+      $test_info = $test_discovery->getTestInfo($test_class);
       return in_array($test_info['type'], $args['types'], TRUE);
     });
   }
