diff --git a/review/simpletest/pifr_simpletest.client.inc b/review/simpletest/pifr_simpletest.client.inc
index c0d9b41..9256f49 100644
--- a/review/simpletest/pifr_simpletest.client.inc
+++ b/review/simpletest/pifr_simpletest.client.inc
@@ -201,49 +201,86 @@ class pifr_client_review_pifr_simpletest extends pifr_client_review_pifr_drupal
     if (!empty($this->arguments['simpletest.tests'])) {
       return '--class ' . implode(',', $this->arguments['simpletest.tests']);
     }
+    // For legacy compatibility with early tests which used drupal.modules
     elseif (!empty($this->arguments['drupal.modules'])) {
       $args = array();
+      // Scan each module's directory tree for .test files
       foreach ($this->arguments['drupal.modules'] as $module) {
-        $testfiles = array();
-        // Scan each module's directory tree for .test files
-        $scan = file_scan_directory($this->checkout_directory . '/' . $this->module_path($module), '\.test$');
-        foreach ($scan as $file) {
-          $testfiles[] = str_replace($this->checkout_directory . '/', '', $file->filename);
-        }
-        $args = array_unique(array_merge($args, $testfiles));
+        $args += $this->findTestFiles($this->module_path($module));
       }
       return '--file ' . implode(',', $args);
     }
+    // This is the current case for contributed projects (but not for core).
     elseif (!empty($this->arguments['test.directory.review'][0])) {
       $args = array();
       // Scan the 'test.directory.review' directory for '.test' files
       foreach ($this->arguments['test.directory.review'] as $directory) {
-        $testfiles = array();
-        $scan = file_scan_directory($this->checkout_directory . '/' . $directory, '\.test$');
-        foreach ($scan as $file) {
-          $testfiles[] = str_replace($this->checkout_directory . '/', '', $file->filename);
-        }
-        $args = array_unique(array_merge($args, $testfiles));
+        $args += $this->findTestFiles($directory);
       }
       return '--file ' . implode(',', $args);
     }
+    // If neither test.directory.review or drupal.modules is present, this
+    // prevents contrib tests from running through a complete core test suite.
     elseif (!($this->is_core_test())) {
       $args = array();
       // Not a core test?  Scan the sites/all/modules/modulename directory
       $this->log("Not a core test.  Scanning module directory.");
-      $scan = file_scan_directory($this->checkout_directory . '/' . $this->module_directory . '/' . $this->project_directory, '\.test$');
-      foreach ($scan as $file) {
-        $args[] = str_replace($this->checkout_directory . '/', '', $file->filename);
-      }
+      $args += $this->findTestFiles($this->module_directory . '/' . $this->project_directory);
       return '--file ' . implode(',', $args);
     }
+    // Short-circuit for the special PIFR self-test helper command.
+    // @todo Move this to the top, and make it core major version dependent.
     elseif (PIFR_SHORTCUT_CORE_TEST) {
       return '--class NonDefaultBlockAdmin';
     }
+    // If none of the above conditions were met, then this is a Drupal core test,
+    // so all available tests need to be run.
     return '--all';
   }
 
   /**
+   * Finds files containing tests.
+   *
+   * File locations and extensions vary on core major version.
+   *
+   * @param string $directory
+   *   A directory to scan within $this->checkout_directory.
+   *
+   * @return array
+   *   A list of filenames that contain tests. Filepaths are relative to
+   *   $this->checkout_directory.
+   *
+   * @see test_list()
+   */
+  protected function findTestFiles($directory) {
+    $basedir = $this->checkout_directory . '/';
+    $files = array();
+
+    // D7-: Find all .test files, which can be located anywhere within $directory.
+    $this->log('Scanning ' . $basedir . $directory . ' for .test files.');
+    foreach (file_scan_directory($basedir . $directory, '\.test$') as $file) {
+      $filename = str_replace($basedir, '', $file->filename);
+      $files[$filename] = $filename;
+    }
+    // D8+: Find all tests in the PSR-0 structure; Drupal\$extension\Tests\*.php
+    // Since we do not want to hard-code too many structural file/directory
+    // assumptions about PSR-0 files and directories, we check for the minimal
+    // conditions only; i.e., a '*.php' file that has '/Tests/' in its path.
+    $this->log('Scanning ' . $basedir . $directory . ' for /Tests/*.php files.');
+    foreach (file_scan_directory($basedir . $directory, '\.php$') as $file) {
+      // '/Tests/' can be contained anywhere in the file's path (there can be
+      // sub-directories below /Tests), but must be contained literally
+      // (case-sensitive).
+      if (strpos($file->filename, '/Tests/')) {
+        $filename = str_replace($basedir, '', $file->filename);
+        $files[$filename] = $filename;
+      }
+    }
+
+    return $files;
+  }
+
+  /**
    * Attempt to identify whether a test is core
    */
   public function is_core_test() {
