diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index cbc946c..69a9792 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -159,6 +159,7 @@ function simpletest_run_tests($test_list, $reporter = 'drupal') {
  * Batch operation callback.
  */
 function _simpletest_batch_operation($test_list_init, $test_id, &$context) {
+  simpletest_register_test_namespaces();
   // Get working values.
   if (!isset($context['sandbox']['max'])) {
     // First iteration: initialize working values.
@@ -291,6 +292,9 @@ function simpletest_log_read($test_id, $prefix, $test_class, $during_test = FALS
  * a static variable. In order to list tests provided by disabled modules
  * hook_registry_files_alter() is used to forcefully add them to the registry.
  *
+ * PSR-0 classes are found by searching the designated directory for each module
+ * for files matching the PSR-0 standard.
+ *
  * @return
  *   An array of tests keyed with the groups specified in each of the tests
  *   getInfo() method and then keyed by the test class. An example of the array
@@ -315,11 +319,45 @@ function simpletest_test_get_all() {
     // information from each tests getInfo() method.
     if ($cache = cache()->get('simpletest')) {
       $groups = $cache->data;
+      simpletest_register_test_namespaces();
     }
     else {
       // Select all clases in files ending with .test.
       $classes = db_query("SELECT name FROM {registry} WHERE type = :type AND filename LIKE :name", array(':type' => 'class', ':name' => '%.test'))->fetchCol();
 
+      // Select all PSR-0 classes in the tests folder of all available modules.
+      // @todo: can profiles/themes have tests as well?
+      $module_list = db_query("SELECT name, filename FROM {system} WHERE type = 'module' ORDER BY weight ASC, name ASC")->fetchAllKeyed();
+
+      // Prepare a list of modules which provide tests.
+      $test_modules = array();
+      foreach ($module_list as $name => $filename) {
+        // Build directory in which the test files would reside.
+        $tests_dir = DRUPAL_ROOT . '/' . dirname($filename) . '/tests/Drupal/' . $name . '/Tests';
+        // Scan it for test files if it exists.
+        if (is_dir($tests_dir)) {
+          $files = file_scan_directory($tests_dir, '/.*\.php/');
+          if (!empty($files)) {
+            $basedir = DRUPAL_ROOT . '/' . dirname($filename) . '/tests/';
+            $test_modules[] = $name;
+            foreach ($files as $file) {
+              // Convert the file name into the namespaced class name.
+              $replacements = array(
+                '/' => '\\',
+                $basedir => '',
+                '.php' => '',
+              );
+              $classes[] = strtr($file->uri, $replacements);
+            }
+          }
+        }
+      }
+
+      // Ensure that namespaces for newly found modules are registered so that
+      // the checks below work.
+      cache()->set('simpletest_modules', $test_modules);
+      simpletest_register_test_namespaces(TRUE);
+
       // Check that each class has a getInfo() method and store the information
       // in an array keyed with the group specified in the test information.
       $groups = array();
@@ -356,6 +394,25 @@ function simpletest_test_get_all() {
 }
 
 /**
+ * Registers test namespaces for all modules which provide tests.
+ */
+function simpletest_register_test_namespaces($force_register = FALSE) {
+  static $called = FALSE;
+
+  // Prevent multiple namespace registrations unless explicitly forced to do so.
+  if (!$called || $force_register) {
+    // Get the cached test modules list and register a test namespace for each.
+    if ($cache = cache()->get('simpletest_modules')) {
+      $loader = drupal_classloader();
+      foreach ($cache->data as $module) {
+        $loader->registerNamespace('Drupal\\' . $module . '\\Tests', DRUPAL_ROOT . '/' . drupal_get_path('module', $module) . '/tests');
+      }
+    }
+    $called = TRUE;
+  }
+}
+
+/**
  * Implements hook_registry_files_alter().
  *
  * Add the test files for disabled modules so that we get a list containing
diff --git a/core/modules/simpletest/simpletest.pages.inc b/core/modules/simpletest/simpletest.pages.inc
index 8ac1ee2..481e4fc 100644
--- a/core/modules/simpletest/simpletest.pages.inc
+++ b/core/modules/simpletest/simpletest.pages.inc
@@ -183,6 +183,7 @@ function theme_simpletest_test_table($variables) {
 function simpletest_test_form_submit($form, &$form_state) {
   // Get list of tests.
   $tests_list = array();
+  simpletest_register_test_namespaces();
   foreach ($form_state['values'] as $class_name => $value) {
     // Since class_exists() will likely trigger an autoload lookup,
     // we do the fast check first.
@@ -233,6 +234,8 @@ function simpletest_result_form($form, &$form_state, $test_id) {
     '#debug' => 0,
   );
 
+  simpletest_register_test_namespaces();
+
   // Cycle through each test group.
   $header = array(t('Message'), t('Group'), t('Filename'), t('Line'), t('Function'), array('colspan' => 2, 'data' => t('Status')));
   $form['result']['results'] = array();
diff --git a/core/modules/tracker/tracker.test b/core/modules/tracker/tests/Drupal/tracker/Tests/TrackerTest.php
similarity index 98%
rename from core/modules/tracker/tracker.test
rename to core/modules/tracker/tests/Drupal/tracker/Tests/TrackerTest.php
index c6d4a29..f0c386d 100644
--- a/core/modules/tracker/tracker.test
+++ b/core/modules/tracker/tests/Drupal/tracker/Tests/TrackerTest.php
@@ -2,9 +2,13 @@
 
 /**
  * @file
- * Tests for tracker.module.
+ * Definition of Drupal\tracker\Tests\TrackerTests
  */
 
+namespace Drupal\tracker\Tests;
+
+use DrupalWebTestCase;
+
 /**
  * Defines a base class for testing tracker.module.
  */
diff --git a/core/modules/tracker/tracker.info b/core/modules/tracker/tracker.info
index a765504..b39eb3f 100644
--- a/core/modules/tracker/tracker.info
+++ b/core/modules/tracker/tracker.info
@@ -4,4 +4,3 @@ dependencies[] = comment
 package = Core
 version = VERSION
 core = 8.x
-files[] = tracker.test
