diff --git a/core/modules/file/src/Tests/Views/RelationshipUserFileDataTest.php b/core/modules/file/src/Tests/Views/RelationshipUserFileDataTest.php
index db49ae1..6115e1a 100644
--- a/core/modules/file/src/Tests/Views/RelationshipUserFileDataTest.php
+++ b/core/modules/file/src/Tests/Views/RelationshipUserFileDataTest.php
@@ -67,7 +67,7 @@ public function testViewsHandlerRelationshipUserFileData() {
       'status' => FILE_STATUS_PERMANENT,
     ]);
     $file->enforceIsNew();
-    file_put_contents($file->getFileUri(), file_get_contents('core/modules/simpletest/files/image-1.png'));
+    file_put_contents($file->getFileUri(), file_get_contents('core/tests/fixtures/files/image-1.png'));
     $file->save();
 
     $account = $this->drupalCreateUser();
diff --git a/core/modules/file/tests/src/Kernel/Migrate/d6/MigrateFileTest.php b/core/modules/file/tests/src/Kernel/Migrate/d6/MigrateFileTest.php
index 7e1cff9..65316d0 100644
--- a/core/modules/file/tests/src/Kernel/Migrate/d6/MigrateFileTest.php
+++ b/core/modules/file/tests/src/Kernel/Migrate/d6/MigrateFileTest.php
@@ -91,7 +91,7 @@ public function testFiles() {
     $this->executeMigration('d6_file');
 
     $file = File::load(2);
-    $this->assertIdentical('public://core/modules/simpletest/files/image-2.jpg', $file->getFileUri());
+    $this->assertIdentical('public://core/tests/fixtures/files/image-2.jpg', $file->getFileUri());
 
     // File 7, created in static::migrateDumpAlter(), shares a path with
     // file 5, which means it should be skipped entirely.
diff --git a/core/modules/image/src/Tests/Views/RelationshipUserImageDataTest.php b/core/modules/image/src/Tests/Views/RelationshipUserImageDataTest.php
index f9381d4..979388c 100644
--- a/core/modules/image/src/Tests/Views/RelationshipUserImageDataTest.php
+++ b/core/modules/image/src/Tests/Views/RelationshipUserImageDataTest.php
@@ -67,7 +67,7 @@ public function testViewsHandlerRelationshipUserImageData() {
       'status' => FILE_STATUS_PERMANENT,
     ]);
     $file->enforceIsNew();
-    file_put_contents($file->getFileUri(), file_get_contents('core/modules/simpletest/files/image-1.png'));
+    file_put_contents($file->getFileUri(), file_get_contents('core/tests/fixtures/files/image-1.png'));
     $file->save();
 
     $account = $this->drupalCreateUser();
diff --git a/core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php b/core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php
index 288ebfb..425b625 100644
--- a/core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php
+++ b/core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php
@@ -45,7 +45,7 @@ public function testSuccessfulCopies() {
     $data_sets = [
       // Test a local to local copy.
       [
-        $this->root . '/core/modules/simpletest/files/image-test.jpg',
+        $this->root . '/core/tests/fixtures/files/image-test.jpg',
         'public://file1.jpg'
       ],
       // Test a temporary file using an absolute path.
@@ -56,7 +56,7 @@ public function testSuccessfulCopies() {
       // Test a temporary file using a relative path.
       [
         $file_absolute,
-        'temporary://core/modules/simpletest/files/test.jpg'
+        'temporary://core/tests/fixtures/files/test.jpg'
       ],
     ];
     foreach ($data_sets as $data) {
@@ -93,7 +93,7 @@ public function testSuccessfulMoves() {
       // Test a temporary file using a relative path.
       [
         $file_2_absolute,
-        'temporary://core/modules/simpletest/files/test.jpg'
+        'temporary://core/tests/fixtures/files/test.jpg'
       ],
     ];
     foreach ($data_sets as $data) {
diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal6.php b/core/modules/migrate_drupal/tests/fixtures/drupal6.php
index 347b2f2..2067345 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal6.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal6.php
@@ -7715,7 +7715,7 @@
   'fid' => '1',
   'uid' => '1',
   'filename' => 'Image1.png',
-  'filepath' => 'core/modules/simpletest/files/image-1.png',
+  'filepath' => 'core/tests/fixtures/files/image-1.png',
   'filemime' => 'image/png',
   'filesize' => '39325',
   'status' => '1',
@@ -7725,7 +7725,7 @@
   'fid' => '2',
   'uid' => '1',
   'filename' => 'Image2.jpg',
-  'filepath' => 'core/modules/simpletest/files/image-2.jpg',
+  'filepath' => 'core/tests/fixtures/files/image-2.jpg',
   'filemime' => 'image/jpeg',
   'filesize' => '1831',
   'status' => '1',
@@ -7735,7 +7735,7 @@
   'fid' => '3',
   'uid' => '1',
   'filename' => 'Image-test.gif',
-  'filepath' => 'core/modules/simpletest/files/image-test.gif',
+  'filepath' => 'core/tests/fixtures/files/image-test.gif',
   'filemime' => 'image/jpeg',
   'filesize' => '183',
   'status' => '1',
@@ -7745,7 +7745,7 @@
   'fid' => '5',
   'uid' => '1',
   'filename' => 'html-1.txt',
-  'filepath' => 'core/modules/simpletest/files/html-1.txt',
+  'filepath' => 'core/tests/fixtures/files/html-1.txt',
   'filemime' => 'text/plain',
   'filesize' => '24',
   'status' => '1',
@@ -31837,8 +31837,8 @@
   'menu_name' => 'navigation',
   'mlid' => '411',
   'plid' => '0',
-  'link_path' => 'core/modules/simpletest/files/imagecache',
-  'router_path' => 'core/modules/simpletest/files/imagecache',
+  'link_path' => 'core/tests/fixtures/files/imagecache',
+  'router_path' => 'core/tests/fixtures/files/imagecache',
   'link_title' => '',
   'options' => 'a:0:{}',
   'module' => 'system',
@@ -39729,7 +39729,7 @@
   'file' => 'sites/all/modules/cck/includes/content.node_form.inc',
 ))
 ->values(array(
-  'path' => 'core/modules/simpletest/files/imagecache',
+  'path' => 'core/tests/fixtures/files/imagecache',
   'load_functions' => '',
   'to_arg_functions' => '',
   'access_callback' => '_imagecache_menu_access_public_files',
@@ -39739,7 +39739,7 @@
   'fit' => '31',
   'number_parts' => '5',
   'tab_parent' => '',
-  'tab_root' => 'core/modules/simpletest/files/imagecache',
+  'tab_root' => 'core/tests/fixtures/files/imagecache',
   'title' => '',
   'title_callback' => 't',
   'title_arguments' => '',
@@ -44575,7 +44575,7 @@
   'status' => '1',
   'timezone' => '3600',
   'language' => 'fr',
-  'picture' => 'core/modules/simpletest/files/image-test.jpg',
+  'picture' => 'core/tests/fixtures/files/image-test.jpg',
   'init' => 'doe@example.com',
   'data' => 'a:2:{s:7:"contact";i:1;s:13:"form_build_id";s:48:"form-qu_DMjE-Vfg01arT5J4VbuBCkOgx_LeySJx4qrPOSuA";}',
   'timezone_name' => 'Europe/Berlin',
@@ -44600,7 +44600,7 @@
   'status' => '1',
   'timezone' => '7200',
   'language' => 'ro',
-  'picture' => 'core/modules/simpletest/files/image-test.png',
+  'picture' => 'core/tests/fixtures/files/image-test.png',
   'init' => 'roe@example.com',
   'data' => 'a:2:{s:7:"contact";i:0;s:13:"form_build_id";s:48:"form-1TxjbL2_1dEHIxEu2Db6OvEsSN1x9ILH1VCgnvsO6LE";}',
   'timezone_name' => 'Europe/Helsinki',
@@ -45539,7 +45539,7 @@
 ))
 ->values(array(
   'name' => 'file_directory_path',
-  'value' => 's:29:"core/modules/simpletest/files";',
+  'value' => 's:25:"core/tests/fixtures/files";',
 ))
 ->values(array(
   'name' => 'file_directory_temp',
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index 2e03af9..516a202 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -22,10 +22,10 @@
 use Drupal\Core\Session\AnonymousUserSession;
 use Drupal\Core\Session\UserSession;
 use Drupal\Core\Site\Settings;
-use Drupal\Core\StreamWrapper\PublicStream;
 use Drupal\Core\Test\AssertMailTrait;
 use Drupal\Core\Url;
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
+use Drupal\Tests\TestFileCreationTrait;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Yaml\Yaml as SymfonyYaml;
@@ -39,6 +39,10 @@
 abstract class WebTestBase extends TestBase {
 
   use AssertContentTrait;
+  use TestFileCreationTrait {
+    getTestFiles as drupalGetTestFiles;
+    compareFiles as drupalCompareFiles;
+  }
   use AssertPageCacheContextsAndTagsTrait;
   use BlockCreationTrait {
     placeBlock as drupalPlaceBlock;
@@ -169,11 +173,6 @@
   protected $sessionId = NULL;
 
   /**
-   * Whether the files were copied to the test files directory.
-   */
-  protected $generatedTestFiles = FALSE;
-
-  /**
    * The maximum number of redirects to follow when handling responses.
    */
   protected $maximumRedirects = 5;
@@ -334,99 +333,6 @@ protected function findBlockInstance(Block $block) {
   }
 
   /**
-   * Gets a list of files that can be used in tests.
-   *
-   * The first time this method is called, it will call
-   * simpletest_generate_file() to generate binary and ASCII text files in the
-   * public:// directory. It will also copy all files in
-   * core/modules/simpletest/files to public://. These contain image, SQL, PHP,
-   * JavaScript, and HTML files.
-   *
-   * All filenames are prefixed with their type and have appropriate extensions:
-   * - text-*.txt
-   * - binary-*.txt
-   * - html-*.html and html-*.txt
-   * - image-*.png, image-*.jpg, and image-*.gif
-   * - javascript-*.txt and javascript-*.script
-   * - php-*.txt and php-*.php
-   * - sql-*.txt and sql-*.sql
-   *
-   * Any subsequent calls will not generate any new files, or copy the files
-   * over again. However, if a test class adds a new file to public:// that
-   * is prefixed with one of the above types, it will get returned as well, even
-   * on subsequent calls.
-   *
-   * @param $type
-   *   File type, possible values: 'binary', 'html', 'image', 'javascript',
-   *   'php', 'sql', 'text'.
-   * @param $size
-   *   (optional) File size in bytes to match. Defaults to NULL, which will not
-   *   filter the returned list by size.
-   *
-   * @return
-   *   List of files in public:// that match the filter(s).
-   */
-  protected function drupalGetTestFiles($type, $size = NULL) {
-    if (empty($this->generatedTestFiles)) {
-      // Generate binary test files.
-      $lines = array(64, 1024);
-      $count = 0;
-      foreach ($lines as $line) {
-        simpletest_generate_file('binary-' . $count++, 64, $line, 'binary');
-      }
-
-      // Generate ASCII text test files.
-      $lines = array(16, 256, 1024, 2048, 20480);
-      $count = 0;
-      foreach ($lines as $line) {
-        simpletest_generate_file('text-' . $count++, 64, $line, 'text');
-      }
-
-      // Copy other test files from simpletest.
-      $original = drupal_get_path('module', 'simpletest') . '/files';
-      $files = file_scan_directory($original, '/(html|image|javascript|php|sql)-.*/');
-      foreach ($files as $file) {
-        file_unmanaged_copy($file->uri, PublicStream::basePath());
-      }
-
-      $this->generatedTestFiles = TRUE;
-    }
-
-    $files = array();
-    // Make sure type is valid.
-    if (in_array($type, array('binary', 'html', 'image', 'javascript', 'php', 'sql', 'text'))) {
-      $files = file_scan_directory('public://', '/' . $type . '\-.*/');
-
-      // If size is set then remove any files that are not of that size.
-      if ($size !== NULL) {
-        foreach ($files as $file) {
-          $stats = stat($file->uri);
-          if ($stats['size'] != $size) {
-            unset($files[$file->uri]);
-          }
-        }
-      }
-    }
-    usort($files, array($this, 'drupalCompareFiles'));
-    return $files;
-  }
-
-  /**
-   * Compare two files based on size and file name.
-   */
-  protected function drupalCompareFiles($file1, $file2) {
-    $compare_size = filesize($file1->uri) - filesize($file2->uri);
-    if ($compare_size) {
-      // Sort by file size.
-      return $compare_size;
-    }
-    else {
-      // The files were the same size, so sort alphabetically.
-      return strnatcmp($file1->name, $file2->name);
-    }
-  }
-
-  /**
    * Log in a user with the internal browser.
    *
    * If a user is already logged in, then the current user is logged out before
diff --git a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserTest.php b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserTest.php
index 9317834..5a677ad 100644
--- a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserTest.php
+++ b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserTest.php
@@ -43,7 +43,7 @@ protected function setUp() {
       'status' => FILE_STATUS_PERMANENT,
     ));
     $file->enforceIsNew();
-    file_put_contents($file->getFileUri(), file_get_contents('core/modules/simpletest/files/image-1.png'));
+    file_put_contents($file->getFileUri(), file_get_contents('core/tests/fixtures/files/image-1.png'));
     $file->save();
 
     $file = File::create(array(
@@ -57,7 +57,7 @@ protected function setUp() {
       'status' => FILE_STATUS_PERMANENT,
     ));
     $file->enforceIsNew();
-    file_put_contents($file->getFileUri(), file_get_contents('core/modules/simpletest/files/image-2.jpg'));
+    file_put_contents($file->getFileUri(), file_get_contents('core/tests/fixtures/files/image-2.jpg'));
     $file->save();
 
     $this->migrateUsers();
diff --git a/core/modules/user/tests/src/Unit/Migrate/d6/UserPictureFileTest.php b/core/modules/user/tests/src/Unit/Migrate/d6/UserPictureFileTest.php
index 6c045ea..e274968 100644
--- a/core/modules/user/tests/src/Unit/Migrate/d6/UserPictureFileTest.php
+++ b/core/modules/user/tests/src/Unit/Migrate/d6/UserPictureFileTest.php
@@ -24,7 +24,7 @@ class UserPictureFileTest extends MigrateSqlSourceTestCase {
   protected $expectedResults = array(
     array(
       'uid' => '2',
-      'picture' => 'core/modules/simpletest/files/image-test.jpg',
+      'picture' => 'core/tests/fixtures/files/image-test.jpg',
     ),
   );
 
@@ -35,7 +35,7 @@ protected function setUp() {
     $this->databaseContents['users'] = array(
       array(
         'uid' => '2',
-        'picture' => 'core/modules/simpletest/files/image-test.jpg',
+        'picture' => 'core/tests/fixtures/files/image-test.jpg',
       ),
       array(
         'uid' => '15',
diff --git a/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php b/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php
index 8362c04..ebd3b56 100644
--- a/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php
+++ b/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php
@@ -23,11 +23,7 @@ class ScanDirectoryTest extends FileTestBase {
 
   protected function setUp() {
     parent::setUp();
-    // Hardcode the location of the simpletest files as it is already known
-    // and shouldn't change, and we don't yet have a way to retrieve their
-    // location from drupal_get_filename() in a cached way.
-    // @todo Remove as part of https://www.drupal.org/node/2186491
-    $this->path = 'core/modules/simpletest/files';
+    $this->path = 'core/tests/fixtures/files';
   }
 
   /**
diff --git a/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php b/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php
index fe36c3d..ba3c0b2 100644
--- a/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php
@@ -42,7 +42,7 @@ class ToolkitGdTest extends KernelTestBase {
    *
    * @var array
    */
-  public static $modules = array('system', 'simpletest');
+  public static $modules = ['system'];
 
   /**
    * {@inheritdoc}
@@ -275,7 +275,7 @@ function testManipulations() {
     foreach ($files as $file) {
       foreach ($operations as $op => $values) {
         // Load up a fresh image.
-        $image = $this->imageFactory->get(drupal_get_path('module', 'simpletest') . '/files/' . $file);
+        $image = $this->imageFactory->get("core/tests/fixtures/files/$file");
         $toolkit = $image->getToolkit();
         if (!$image->isValid()) {
           $this->fail(SafeMarkup::format('Could not load image %file.', array('%file' => $file)));
@@ -421,14 +421,14 @@ function testManipulations() {
    */
   public function testResourceDestruction() {
     // Test that an Image object going out of scope releases its GD resource.
-    $image = $this->imageFactory->get(drupal_get_path('module', 'simpletest') . '/files/image-test.png');
+    $image = $this->imageFactory->get('core/tests/fixtures/files/image-test.png');
     $res = $image->getToolkit()->getResource();
     $this->assertTrue(is_resource($res), 'Successfully loaded image resource.');
     $image = NULL;
     $this->assertFalse(is_resource($res), 'Image resource was destroyed after losing scope.');
 
     // Test that 'create_new' operation does not leave orphaned GD resources.
-    $image = $this->imageFactory->get(drupal_get_path('module', 'simpletest') . '/files/image-test.png');
+    $image = $this->imageFactory->get('core/tests/fixtures/files/image-test.png');
     $old_res = $image->getToolkit()->getResource();
     // Check if resource has been created successfully.
     $this->assertTrue(is_resource($old_res));
@@ -451,7 +451,7 @@ function testGifTransparentImages() {
     // Test loading an indexed GIF image with transparent color set.
     // Color at top-right pixel should be fully transparent.
     $file = 'image-test-transparent-indexed.gif';
-    $image = $this->imageFactory->get(drupal_get_path('module', 'simpletest') . '/files/' . $file);
+    $image = $this->imageFactory->get("core/tests/fixtures/files/$file");
     $resource = $image->getToolkit()->getResource();
     $color_index = imagecolorat($resource, $image->getWidth() - 1, 0);
     $color = array_values(imagecolorsforindex($resource, $color_index));
@@ -485,14 +485,14 @@ function testGifTransparentImages() {
     // of 6 colors, and setting the transparent color index to 6 (one higher
     // than the largest allowed index), as follows:
     // @code
-    // $image = imagecreatefromgif('core/modules/simpletest/files/image-test.gif');
+    // $image = imagecreatefromgif('core/tests/fixtures/files/image-test.gif');
     // imagecolortransparent($image, 6);
-    // imagegif($image, 'core/modules/simpletest/files/image-test-transparent-out-of-range.gif');
+    // imagegif($image, 'core/tests/fixtures/files/image-test-transparent-out-of-range.gif');
     // @endcode
     // This allows us to test that an image with an out-of-range color index
     // can be loaded correctly.
     $file = 'image-test-transparent-out-of-range.gif';
-    $image = $this->imageFactory->get(drupal_get_path('module', 'simpletest') . '/files/' . $file);
+    $image = $this->imageFactory->get("core/tests/fixtures/files/$file");
     $toolkit = $image->getToolkit();
 
     if (!$image->isValid()) {
@@ -517,7 +517,7 @@ function testMissingOperation() {
     $file = 'image-test.png';
 
     // Load up a fresh image.
-    $image = $this->imageFactory->get(drupal_get_path('module', 'simpletest') . '/files/' . $file);
+    $image = $this->imageFactory->get("core/tests/fixtures/files/$file");
     if (!$image->isValid()) {
       $this->fail(SafeMarkup::format('Could not load image %file.', array('%file' => $file)));
     }
diff --git a/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php b/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php
index 060ee46..f552774 100644
--- a/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php
@@ -27,7 +27,7 @@ function testInstallerTranslationFiles() {
 
     // Hardcode the simpletest module location as we don't yet know where it is.
     // @todo Remove as part of https://www.drupal.org/node/2186491
-    $file_translation = new FileTranslation('core/modules/simpletest/files/translations');
+    $file_translation = new FileTranslation('core/tests/fixtures/files/translations');
     foreach ($expected_translation_files as $langcode => $files_expected) {
       $files_found = $file_translation->findTranslationFiles($langcode);
       $this->assertTrue(count($files_found) == count($files_expected), format_string('@count installer languages found.', array('@count' => count($files_expected))));
diff --git a/core/tests/Drupal/Tests/TestFileCreationTrait.php b/core/tests/Drupal/Tests/TestFileCreationTrait.php
new file mode 100644
index 0000000..b9b253c
--- /dev/null
+++ b/core/tests/Drupal/Tests/TestFileCreationTrait.php
@@ -0,0 +1,171 @@
+<?php
+
+namespace Drupal\Tests;
+
+use Drupal\Core\StreamWrapper\PublicStream;
+
+/**
+ * Provides methods to create test files from given values.
+ *
+ * This trait is meant to be used only by test classes.
+ */
+trait TestFileCreationTrait {
+
+  /**
+   * Whether the files were copied to the test files directory.
+   *
+   * @var bool
+   */
+  protected $generatedTestFiles = FALSE;
+
+  /**
+   * Gets a list of files that can be used in tests.
+   *
+   * The first time this method is called, it will call
+   * $this->generateFile() to generate binary and ASCII text files in the
+   * public:// directory. It will also copy all files in
+   * core/tests/fixtures/files to public://. These contain image, SQL, PHP,
+   * JavaScript, and HTML files.
+   *
+   * All filenames are prefixed with their type and have appropriate extensions:
+   * - text-*.txt
+   * - binary-*.txt
+   * - html-*.html and html-*.txt
+   * - image-*.png, image-*.jpg, and image-*.gif
+   * - javascript-*.txt and javascript-*.script
+   * - php-*.txt and php-*.php
+   * - sql-*.txt and sql-*.sql
+   *
+   * Any subsequent calls will not generate any new files, or copy the files
+   * over again. However, if a test class adds a new file to public:// that
+   * is prefixed with one of the above types, it will get returned as well, even
+   * on subsequent calls.
+   *
+   * @param $type
+   *   File type, possible values: 'binary', 'html', 'image', 'javascript',
+   *   'php', 'sql', 'text'.
+   * @param $size
+   *   (optional) File size in bytes to match. Defaults to NULL, which will not
+   *   filter the returned list by size.
+   *
+   * @return array[]
+   *   List of files in public:// that match the filter(s).
+   */
+  protected function getTestFiles($type, $size = NULL) {
+    if (empty($this->generatedTestFiles)) {
+      // Generate binary test files.
+      $lines = [64, 1024];
+      $count = 0;
+      foreach ($lines as $line) {
+        $this->generateFile('binary-' . $count++, 64, $line, 'binary');
+      }
+
+      // Generate ASCII text test files.
+      $lines = [16, 256, 1024, 2048, 20480];
+      $count = 0;
+      foreach ($lines as $line) {
+        $this->generateFile('text-' . $count++, 64, $line, 'text');
+      }
+
+      // Copy other test files.
+      $original = 'core/tests/fixtures/files';
+      $files = file_scan_directory($original, '/(html|image|javascript|php|sql)-.*/');
+      foreach ($files as $file) {
+        file_unmanaged_copy($file->uri, PublicStream::basePath());
+      }
+
+      $this->generatedTestFiles = TRUE;
+    }
+
+    $files = [];
+    // Make sure type is valid.
+    if (in_array($type, ['binary', 'html', 'image', 'javascript', 'php', 'sql', 'text'])) {
+      $files = file_scan_directory('public://', '/' . $type . '\-.*/');
+
+      // If size is set then remove any files that are not of that size.
+      if ($size !== NULL) {
+        foreach ($files as $file) {
+          $stats = stat($file->uri);
+          if ($stats['size'] != $size) {
+            unset($files[$file->uri]);
+          }
+        }
+      }
+    }
+    usort($files, [$this, 'compareFiles']);
+    return $files;
+  }
+
+  /**
+   * Compares two files based on size and file name.
+   *
+   * Callback for uasort() within \TestFileCreationTrait::getTestFiles().
+   *
+   * @param \stdClass $file1
+   *   The first file.
+   * @param \stdClass $file2
+   *   The second class.
+   *
+   * @return int
+   */
+  protected function compareFiles($file1, $file2) {
+    $compare_size = filesize($file1->uri) - filesize($file2->uri);
+    if ($compare_size) {
+      // Sort by file size.
+      return $compare_size;
+    }
+    else {
+      // The files were the same size, so sort alphabetically.
+      return strnatcmp($file1->name, $file2->name);
+    }
+  }
+
+  /**
+   * Generates a test file.
+   *
+   * @param string $filename
+   *   The name of the file, including the path. The suffix '.txt' is appended
+   *   to the supplied file name and the file is put into the public:// files
+   *   directory.
+   * @param int $width
+   *   The number of characters on one line.
+   * @param int $lines
+   *   The number of lines in the file.
+   * @param string $type
+   *   (optional) The type, one of:
+   *   - text: The generated file contains random ASCII characters.
+   *   - binary: The generated file contains random characters whose codes are
+   *     in the range of 0 to 31.
+   *   - binary-text: The generated file contains random sequence of '0' and '1'
+   *     values.
+   *
+   * @return string
+   *   The name of the file, including the path.
+   */
+  public static function generateFile($filename, $width, $lines, $type = 'binary-text') {
+    $text = '';
+    for ($i = 0; $i < $lines; $i++) {
+      // Generate $width - 1 characters to leave space for the "\n" character.
+      for ($j = 0; $j < $width - 1; $j++) {
+        switch ($type) {
+          case 'text':
+            $text .= chr(rand(32, 126));
+            break;
+          case 'binary':
+            $text .= chr(rand(0, 31));
+            break;
+          case 'binary-text':
+          default:
+            $text .= rand(0, 1);
+            break;
+        }
+      }
+      $text .= "\n";
+    }
+
+    // Create filename.
+    file_put_contents('public://' . $filename . '.txt', $text);
+    return $filename;
+  }
+
+}
diff --git a/core/modules/simpletest/files/README.txt b/core/tests/fixtures/files/README.txt
similarity index 100%
rename from core/modules/simpletest/files/README.txt
rename to core/tests/fixtures/files/README.txt
diff --git a/core/modules/simpletest/files/html-1.txt b/core/tests/fixtures/files/html-1.txt
similarity index 100%
rename from core/modules/simpletest/files/html-1.txt
rename to core/tests/fixtures/files/html-1.txt
diff --git a/core/modules/simpletest/files/html-2.html b/core/tests/fixtures/files/html-2.html
similarity index 100%
rename from core/modules/simpletest/files/html-2.html
rename to core/tests/fixtures/files/html-2.html
diff --git a/core/modules/simpletest/files/image-1.png b/core/tests/fixtures/files/image-1.png
similarity index 100%
rename from core/modules/simpletest/files/image-1.png
rename to core/tests/fixtures/files/image-1.png
diff --git a/core/modules/simpletest/files/image-2.jpg b/core/tests/fixtures/files/image-2.jpg
similarity index 100%
rename from core/modules/simpletest/files/image-2.jpg
rename to core/tests/fixtures/files/image-2.jpg
diff --git a/core/modules/simpletest/files/image-test-no-transparency.gif b/core/tests/fixtures/files/image-test-no-transparency.gif
similarity index 100%
rename from core/modules/simpletest/files/image-test-no-transparency.gif
rename to core/tests/fixtures/files/image-test-no-transparency.gif
diff --git a/core/modules/simpletest/files/image-test-transparent-indexed.gif b/core/tests/fixtures/files/image-test-transparent-indexed.gif
similarity index 100%
rename from core/modules/simpletest/files/image-test-transparent-indexed.gif
rename to core/tests/fixtures/files/image-test-transparent-indexed.gif
diff --git a/core/modules/simpletest/files/image-test-transparent-out-of-range.gif b/core/tests/fixtures/files/image-test-transparent-out-of-range.gif
similarity index 100%
rename from core/modules/simpletest/files/image-test-transparent-out-of-range.gif
rename to core/tests/fixtures/files/image-test-transparent-out-of-range.gif
diff --git a/core/modules/simpletest/files/image-test.gif b/core/tests/fixtures/files/image-test.gif
similarity index 100%
rename from core/modules/simpletest/files/image-test.gif
rename to core/tests/fixtures/files/image-test.gif
diff --git a/core/modules/simpletest/files/image-test.jpg b/core/tests/fixtures/files/image-test.jpg
similarity index 100%
rename from core/modules/simpletest/files/image-test.jpg
rename to core/tests/fixtures/files/image-test.jpg
diff --git a/core/modules/simpletest/files/image-test.png b/core/tests/fixtures/files/image-test.png
similarity index 100%
rename from core/modules/simpletest/files/image-test.png
rename to core/tests/fixtures/files/image-test.png
diff --git a/core/modules/simpletest/files/javascript-1.txt b/core/tests/fixtures/files/javascript-1.txt
similarity index 100%
rename from core/modules/simpletest/files/javascript-1.txt
rename to core/tests/fixtures/files/javascript-1.txt
diff --git a/core/modules/simpletest/files/javascript-2.script b/core/tests/fixtures/files/javascript-2.script
similarity index 100%
rename from core/modules/simpletest/files/javascript-2.script
rename to core/tests/fixtures/files/javascript-2.script
diff --git a/core/modules/simpletest/files/php-1.txt b/core/tests/fixtures/files/php-1.txt
similarity index 100%
rename from core/modules/simpletest/files/php-1.txt
rename to core/tests/fixtures/files/php-1.txt
diff --git a/core/modules/simpletest/files/php-2.php b/core/tests/fixtures/files/php-2.php
similarity index 100%
rename from core/modules/simpletest/files/php-2.php
rename to core/tests/fixtures/files/php-2.php
diff --git a/core/modules/simpletest/files/sql-1.txt b/core/tests/fixtures/files/sql-1.txt
similarity index 100%
rename from core/modules/simpletest/files/sql-1.txt
rename to core/tests/fixtures/files/sql-1.txt
diff --git a/core/modules/simpletest/files/sql-2.sql b/core/tests/fixtures/files/sql-2.sql
similarity index 100%
rename from core/modules/simpletest/files/sql-2.sql
rename to core/tests/fixtures/files/sql-2.sql
diff --git a/core/modules/simpletest/files/translations/drupal-8.0.0-beta2.hu.po b/core/tests/fixtures/files/translations/drupal-8.0.0-beta2.hu.po
similarity index 100%
rename from core/modules/simpletest/files/translations/drupal-8.0.0-beta2.hu.po
rename to core/tests/fixtures/files/translations/drupal-8.0.0-beta2.hu.po
diff --git a/core/modules/simpletest/files/translations/drupal-8.0.0.de.po b/core/tests/fixtures/files/translations/drupal-8.0.0.de.po
similarity index 100%
rename from core/modules/simpletest/files/translations/drupal-8.0.0.de.po
rename to core/tests/fixtures/files/translations/drupal-8.0.0.de.po
