diff --git a/core/lib/Drupal/Core/Test/TestDatabase.php b/core/lib/Drupal/Core/Test/TestDatabase.php
index 682c792..b465891 100644
--- a/core/lib/Drupal/Core/Test/TestDatabase.php
+++ b/core/lib/Drupal/Core/Test/TestDatabase.php
@@ -168,4 +168,50 @@ protected function getLockFile($lock_id) {
     return FileSystem::getOsTemporaryDirectory() . '/test_' . $lock_id;
   }
 
+  /**
+   * Store an assertion from outside the testing context.
+   *
+   * This is useful for inserting assertions that can only be recorded after
+   * the test case has been destroyed, such as PHP fatal errors. The caller
+   * information is not automatically gathered since the caller is most likely
+   * inserting the assertion on behalf of other code. In all other respects
+   * the method behaves just like \Drupal\simpletest\TestBase::assert() in terms
+   * of storing the assertion.
+   *
+   * @return
+   *   Message ID of the stored assertion.
+   *
+   * @see \Drupal\simpletest\TestBase::assert()
+   * @see \Drupal\simpletest\TestBase::deleteAssert()
+   */
+  public static function insertAssert($test_id, $test_class, $status, $message = '', $group = 'Other', array $caller = array()) {
+    // Convert boolean status to string status.
+    if (is_bool($status)) {
+      $status = $status ? 'pass' : 'fail';
+    }
+
+    $caller += array(
+      'function' => 'Unknown',
+      'line' => 0,
+      'file' => 'Unknown',
+    );
+
+    $assertion = array(
+      'test_id' => $test_id,
+      'test_class' => $test_class,
+      'status' => $status,
+      'message' => $message,
+      'message_group' => $group,
+      'function' => $caller['function'],
+      'line' => $caller['line'],
+      'file' => $caller['file'],
+    );
+
+    // We can't use storeAssertion() because this method is static.
+    return self::getConnection()
+      ->insert('simpletest')
+      ->fields($assertion)
+      ->execute();
+  }
+
 }
diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index 77128aa..0e564bb 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -9,7 +9,6 @@
 use Drupal\Core\Database\Database;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\simpletest\TestBase;
 use Drupal\Core\Test\TestDatabase;
 use Drupal\simpletest\TestDiscovery;
 use Symfony\Component\Process\PhpExecutableFinder;
@@ -547,11 +546,11 @@ function simpletest_log_read($test_id, $database_prefix, $test_class) {
           'line' => $match[4],
           'file' => $match[3],
         );
-        TestBase::insertAssert($test_id, $test_class, FALSE, $match[2], $match[1], $caller);
+        TestDatabase::insertAssert($test_id, $test_class, FALSE, $match[2], $match[1], $caller);
       }
       else {
         // Unknown format, place the entire message in the log.
-        TestBase::insertAssert($test_id, $test_class, FALSE, $line, 'Fatal error');
+        TestDatabase::insertAssert($test_id, $test_class, FALSE, $line, 'Fatal error');
       }
       $found = TRUE;
     }
@@ -647,6 +646,10 @@ function simpletest_generate_file($filename, $width, $lines, $type = 'binary-tex
  * Removes all temporary database tables and directories.
  */
 function simpletest_clean_environment() {
+  // We have to register the test namespaces so that core's test classes are
+  // accessible to these functions.
+  // @todo: Remove/refactor in https://www.drupal.org/node/2800267
+  \Drupal::service('test_discovery')->registerTestNamespaces();
   simpletest_clean_database();
   simpletest_clean_temporary_directories();
   if (\Drupal::config('simpletest.settings')->get('clear_results')) {
diff --git a/core/modules/simpletest/src/TestBase.php b/core/modules/simpletest/src/TestBase.php
index 5fb36a4..07e0046 100644
--- a/core/modules/simpletest/src/TestBase.php
+++ b/core/modules/simpletest/src/TestBase.php
@@ -457,33 +457,7 @@ protected function assert($status, $message = '', $group = 'Other', array $calle
    * @see \Drupal\simpletest\TestBase::deleteAssert()
    */
   public static function insertAssert($test_id, $test_class, $status, $message = '', $group = 'Other', array $caller = array()) {
-    // Convert boolean status to string status.
-    if (is_bool($status)) {
-      $status = $status ? 'pass' : 'fail';
-    }
-
-    $caller += array(
-      'function' => 'Unknown',
-      'line' => 0,
-      'file' => 'Unknown',
-    );
-
-    $assertion = array(
-      'test_id' => $test_id,
-      'test_class' => $test_class,
-      'status' => $status,
-      'message' => $message,
-      'message_group' => $group,
-      'function' => $caller['function'],
-      'line' => $caller['line'],
-      'file' => $caller['file'],
-    );
-
-    // We can't use storeAssertion() because this method is static.
-    return self::getDatabaseConnection()
-      ->insert('simpletest')
-      ->fields($assertion)
-      ->execute();
+    return TestDatabase::insertAssert($test_id, $test_class, $status, $message, $group, $caller);
   }
 
   /**
@@ -969,7 +943,7 @@ public function run(array $methods = array()) {
         'file' => $object_info->getFileName(),
       );
       foreach ($missing_requirements as $missing_requirement) {
-        TestBase::insertAssert($this->testId, $class, FALSE, $missing_requirement, 'Requirements check', $caller);
+        TestDatabase::insertAssert($this->testId, $class, FALSE, $missing_requirement, 'Requirements check', $caller);
       }
       return;
     }
@@ -1028,7 +1002,7 @@ public function run(array $methods = array()) {
         'line' => $method_info->getStartLine(),
         'function' => $class . '->' . $method . '()',
       );
-      $test_completion_check_id = TestBase::insertAssert($this->testId, $class, FALSE, 'The test did not complete due to a fatal error.', 'Completion check', $caller);
+      $test_completion_check_id = TestDatabase::insertAssert($this->testId, $class, FALSE, 'The test did not complete due to a fatal error.', 'Completion check', $caller);
 
       try {
         $this->prepareEnvironment();
@@ -1534,6 +1508,11 @@ public static function generatePermutations($parameters) {
    * Some tests chmod generated files to be read only. During
    * TestBase::restoreEnvironment() and other cleanup operations, these files
    * need to get deleted too.
+   *
+   * @param string $path
+   *   The path about to be deleted.
+   *
+   * @todo Remove/refactor in https://www.drupal.org/node/2800267
    */
   public static function filePreDeleteCallback($path) {
     chmod($path, 0700);
