diff --git a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityDisplayTest.php b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityDisplayTest.php
index 14b3536..3dbbaec 100644
--- a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityDisplayTest.php
+++ b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityDisplayTest.php
@@ -25,8 +25,8 @@ class MigrateCommentEntityDisplayTest extends MigrateDrupal7TestBase {
   protected function setUp() {
     parent::setUp();
     $this->installConfig(static::$modules);
+    $this->migrateContentTypes();
     $this->executeMigrations([
-      'd7_node_type',
       'd7_comment_type',
       'd7_comment_field',
       'd7_comment_field_instance',
diff --git a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityFormDisplaySubjectTest.php b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityFormDisplaySubjectTest.php
index c261ffb..075ba00 100644
--- a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityFormDisplaySubjectTest.php
+++ b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityFormDisplaySubjectTest.php
@@ -25,8 +25,8 @@ class MigrateCommentEntityFormDisplaySubjectTest extends MigrateDrupal7TestBase
   protected function setUp() {
     parent::setUp();
     $this->installConfig(static::$modules);
+    $this->migrateContentTypes();
     $this->executeMigrations([
-      'd7_node_type',
       'd7_comment_type',
       'd7_comment_entity_form_display_subject',
     ]);
diff --git a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityFormDisplayTest.php b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityFormDisplayTest.php
index 2700a4c..792cffb 100644
--- a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityFormDisplayTest.php
+++ b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentEntityFormDisplayTest.php
@@ -25,8 +25,8 @@ class MigrateCommentEntityFormDisplayTest extends MigrateDrupal7TestBase {
   protected function setUp() {
     parent::setUp();
     $this->installConfig(static::$modules);
+    $this->migrateContentTypes();
     $this->executeMigrations([
-      'd7_node_type',
       'd7_comment_type',
       'd7_comment_field',
       'd7_comment_field_instance',
diff --git a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentFieldInstanceTest.php b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentFieldInstanceTest.php
index c84621b..e527572 100644
--- a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentFieldInstanceTest.php
+++ b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentFieldInstanceTest.php
@@ -28,8 +28,8 @@ class MigrateCommentFieldInstanceTest extends MigrateDrupal7TestBase {
   protected function setUp() {
     parent::setUp();
     $this->installConfig(static::$modules);
+    $this->migrateContentTypes();
     $this->executeMigrations([
-      'd7_node_type',
       'd7_comment_type',
       'd7_comment_field',
       'd7_comment_field_instance',
diff --git a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentFieldTest.php b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentFieldTest.php
index bf93f71..7b1bed6 100644
--- a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentFieldTest.php
+++ b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentFieldTest.php
@@ -27,8 +27,8 @@ class MigrateCommentFieldTest extends MigrateDrupal7TestBase {
   protected function setUp() {
     parent::setUp();
     $this->installConfig(static::$modules);
+    $this->migrateContentTypes();
     $this->executeMigrations([
-      'd7_node_type',
       'd7_comment_type',
       'd7_comment_field',
     ]);
diff --git a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentTest.php b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentTest.php
index 8d6e668..c6383d9 100644
--- a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentTest.php
+++ b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentTest.php
@@ -19,36 +19,14 @@
  */
 class MigrateCommentTest extends MigrateDrupal7TestBase {
 
-  public static $modules = ['filter', 'node', 'comment', 'text'];
-
   /**
    * {@inheritdoc}
    */
   protected function setUp() {
     parent::setUp();
-
     $this->installConfig(static::$modules);
-    $this->installEntitySchema('node');
-    $this->installEntitySchema('comment');
-
-    $this->executeMigrations([
-      'd7_filter_format',
-      'd7_user_role',
-      'd7_user',
-    ]);
-    $this->executeMigration('d7_node_type');
-    // We only need the test_content_type node migration to run for real, so
-    // mock all the others.
-    $this->prepareMigrations(array(
-      'd7_node:*' => array(
-        array(array(0), array(0)),
-      ),
-    ));
-    $this->executeMigrations([
-      'd7_node__test_content_type',
-      'd7_comment_type',
-      'd7_comment',
-    ]);
+    $this->migrateContent(FALSE);
+    $this->executeMigrations(['d7_comment_type', 'd7_comment']);
   }
 
   /**
diff --git a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentTypeTest.php b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentTypeTest.php
index 409631d..6e5206d 100644
--- a/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentTypeTest.php
+++ b/core/modules/comment/src/Tests/Migrate/d7/MigrateCommentTypeTest.php
@@ -27,8 +27,8 @@ class MigrateCommentTypeTest extends MigrateDrupal7TestBase {
   protected function setUp() {
     parent::setUp();
     $this->installConfig(static::$modules);
+    $this->migrateContentTypes();
     $this->executeMigrations([
-      'd7_node_type',
       'd7_comment_type',
     ]);
   }
diff --git a/core/modules/field/src/Tests/Migrate/d7/MigrateFieldFormatterSettingsTest.php b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldFormatterSettingsTest.php
index 246b1e5..842f461 100644
--- a/core/modules/field/src/Tests/Migrate/d7/MigrateFieldFormatterSettingsTest.php
+++ b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldFormatterSettingsTest.php
@@ -150,12 +150,7 @@ protected function setUp() {
       ->condition('field_name', 'body')
       ->execute();
 
-    $this->executeMigrations([
-      'd7_field',
-      'd7_field_instance',
-      'd7_view_modes',
-      'd7_field_formatter_settings',
-    ]);
+    $this->migrateFields();
   }
 
   /**
diff --git a/core/modules/field/src/Tests/Migrate/d7/MigrateFieldInstanceWidgetSettingsTest.php b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldInstanceWidgetSettingsTest.php
index f6dbd46..749264e 100644
--- a/core/modules/field/src/Tests/Migrate/d7/MigrateFieldInstanceWidgetSettingsTest.php
+++ b/core/modules/field/src/Tests/Migrate/d7/MigrateFieldInstanceWidgetSettingsTest.php
@@ -46,14 +46,7 @@ protected function setUp() {
     $this->installEntitySchema('comment');
     $this->installEntitySchema('taxonomy_term');
     $this->installConfig(static::$modules);
-
-    $this->executeMigrations([
-      'd7_node_type',
-      'd7_comment_type',
-      'd7_field',
-      'd7_field_instance',
-      'd7_field_instance_widget_settings',
-    ]);
+    $this->migrateFields();
   }
 
   /**
diff --git a/core/modules/file/config/schema/file.destination.schema.yml b/core/modules/file/config/schema/file.destination.schema.yml
index c6b197f..e7049ac 100644
--- a/core/modules/file/config/schema/file.destination.schema.yml
+++ b/core/modules/file/config/schema/file.destination.schema.yml
@@ -8,3 +8,6 @@ migrate.destination.entity:file:
     urlencode:
       type: boolean
       label: 'Whether to urlencode incoming file paths'
+    source_base_path:
+      type: string
+      label: 'Source base path'
diff --git a/core/modules/migrate_drupal/src/Tests/d7/MigrateDrupal7TestBase.php b/core/modules/migrate_drupal/src/Tests/d7/MigrateDrupal7TestBase.php
index 63e8e67..e3bce57 100644
--- a/core/modules/migrate_drupal/src/Tests/d7/MigrateDrupal7TestBase.php
+++ b/core/modules/migrate_drupal/src/Tests/d7/MigrateDrupal7TestBase.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\migrate_drupal\Tests\d7;
 
+use Drupal\migrate\Entity\Migration;
 use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
 
 /**
@@ -17,10 +18,121 @@
   /**
    * {@inheritdoc}
    */
+  public static $modules = [
+    'comment',
+    'datetime',
+    'entity_reference',
+    'filter',
+    'image',
+    'link',
+    'node',
+    'taxonomy',
+    'telephone',
+    'text',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
   protected function setUp() {
     parent::setUp();
     $this->loadFixture(__DIR__ . '/../../../tests/fixtures/drupal7.php');
     $this->installMigrations('Drupal 7');
+
+    $this->installEntitySchema('comment');
+    $this->installEntitySchema('file');
+    $this->installEntitySchema('node');
+    $this->installEntitySchema('taxonomy_term');
+  }
+
+  /**
+   * Executes all user migrations.
+   *
+   * @param bool $include_pictures
+   *   If TRUE, migrates user pictures.
+   */
+  protected function migrateUsers($include_pictures = TRUE) {
+    $this->executeMigrations(['d7_filter_format', 'd7_user_role']);
+
+    if ($include_pictures) {
+      // The d7_file source plugin depends on source_base_path being set in
+      // the destination configuration. This is evil and horrifying, but
+      // necessary for the time being.
+      // @see https://www.drupal.org/node/2577871
+      /** @var \Drupal\migrate\Entity\MigrationInterface $d7_file */
+      $d7_file = Migration::load('d7_file');
+      $destination = $d7_file->get('destination');
+      $destination['source_base_path'] = $this->siteDirectory;
+      $d7_file->set('destination', $destination);
+      $d7_file->save();
+
+      $this->executeMigrations([
+        'd7_file',
+        'user_picture_field',
+        'user_picture_field_instance',
+        'user_picture_entity_display',
+        'user_picture_entity_form_display',
+      ]);
+    }
+    else {
+      // These are optional dependencies of d7_user, but we don't need them if
+      // we're not migrating user pictures.
+      Migration::load('user_picture_entity_display')->delete();
+      Migration::load('user_picture_entity_form_display')->delete();
+    }
+
+    $this->executeMigration('d7_user');
+  }
+
+  /**
+   * Migrates node types.
+   */
+  protected function migrateContentTypes() {
+    $this->installConfig(['node']);
+    $this->executeMigration('d7_node_type');
+  }
+
+  /**
+   * Executes all field migrations.
+   */
+  protected function migrateFields() {
+    $this->migrateContentTypes();
+    $this->installConfig(['comment']);
+    $this->executeMigrations([
+      'd7_comment_type',
+      'd7_field',
+      'd7_field_instance',
+      'd7_field_instance_widget_settings',
+      'd7_view_modes',
+      'd7_field_formatter_settings',
+    ]);
+  }
+
+  /**
+   * Executes all content migrations.
+   *
+   * @param bool $include_revisions
+   *   If TRUE, migrates node revisions.
+   */
+  protected function migrateContent($include_revisions = FALSE) {
+    $this->migrateUsers(FALSE);
+    $this->migrateFields();
+    $this->executeMigrations(['d7_node_settings', 'd7_node:*']);
+
+    if ($include_revisions) {
+      $this->executeMigrations(['d7_node_revision:*']);
+    }
+  }
+
+  /**
+   * Executes all taxonomy migrations.
+   */
+  protected function migrateTaxonomy() {
+    $this->migrateContentTypes();
+    $this->executeMigrations([
+      'd7_taxonomy_vocabulary',
+      'd7_taxonomy_term',
+    ]);
   }
 
 }
diff --git a/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTest.php b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTest.php
index 9a9024b..f4375ea 100644
--- a/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTest.php
+++ b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTest.php
@@ -36,22 +36,13 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
   protected function setUp() {
     parent::setUp();
 
-    $this->installEntitySchema('node');
     $this->installEntitySchema('comment');
     $this->installEntitySchema('taxonomy_term');
     $this->installConfig(static::$modules);
     $this->installSchema('node', ['node_access']);
     $this->installSchema('system', ['sequences']);
 
-    $this->executeMigrations([
-      'd7_user_role',
-      'd7_user',
-      'd7_node_type',
-      'd7_comment_type',
-      'd7_field',
-      'd7_field_instance',
-      'd7_node__test_content_type',
-    ]);
+    $this->migrateContent();
   }
 
   /**
diff --git a/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTypeTest.php b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTypeTest.php
index c3706a9..3ada045 100644
--- a/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTypeTest.php
+++ b/core/modules/node/src/Tests/Migrate/d7/MigrateNodeTypeTest.php
@@ -32,8 +32,7 @@ class MigrateNodeTypeTest extends MigrateDrupal7TestBase {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installConfig(array('node'));
-    $this->executeMigration('d7_node_type');
+    $this->migrateContentTypes();
   }
 
   /**
diff --git a/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomyTermTest.php b/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomyTermTest.php
index 64dabde..83918ad 100644
--- a/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomyTermTest.php
+++ b/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomyTermTest.php
@@ -25,8 +25,7 @@ class MigrateTaxonomyTermTest extends MigrateDrupal7TestBase {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installEntitySchema('taxonomy_term');
-    $this->executeMigrations(['d7_taxonomy_vocabulary', 'd7_taxonomy_term']);
+    $this->migrateTaxonomy();
   }
 
   /**
diff --git a/core/modules/tracker/src/Tests/Migrate/d7/MigrateTrackerNodeTest.php b/core/modules/tracker/src/Tests/Migrate/d7/MigrateTrackerNodeTest.php
index 521e74d..2cb0f2c 100644
--- a/core/modules/tracker/src/Tests/Migrate/d7/MigrateTrackerNodeTest.php
+++ b/core/modules/tracker/src/Tests/Migrate/d7/MigrateTrackerNodeTest.php
@@ -36,11 +36,11 @@ protected function setUp() {
     $this->installConfig(static::$modules);
     $this->installSchema('node', ['node_access']);
     $this->installSchema('tracker', ['tracker_node', 'tracker_user']);
+    $this->migrateContentTypes();
 
     $this->executeMigrations([
       'd7_user_role',
       'd7_user',
-      'd7_node_type',
       'd7_node__test_content_type',
       'd7_tracker_node',
     ]);
diff --git a/core/modules/tracker/src/Tests/Migrate/d7/MigrateTrackerUserTest.php b/core/modules/tracker/src/Tests/Migrate/d7/MigrateTrackerUserTest.php
index a9b4a39..d3dfcbc 100644
--- a/core/modules/tracker/src/Tests/Migrate/d7/MigrateTrackerUserTest.php
+++ b/core/modules/tracker/src/Tests/Migrate/d7/MigrateTrackerUserTest.php
@@ -36,11 +36,11 @@ protected function setUp() {
     $this->installConfig(static::$modules);
     $this->installSchema('node', ['node_access']);
     $this->installSchema('tracker', ['tracker_node', 'tracker_user']);
+    $this->migrateContentTypes();
 
     $this->executeMigrations([
       'd7_user_role',
       'd7_user',
-      'd7_node_type',
       'd7_node__test_content_type',
       'd7_tracker_node',
     ]);
diff --git a/core/modules/user/src/Tests/Migrate/d7/MigrateUserTest.php b/core/modules/user/src/Tests/Migrate/d7/MigrateUserTest.php
index 149672b..c00ef2e 100644
--- a/core/modules/user/src/Tests/Migrate/d7/MigrateUserTest.php
+++ b/core/modules/user/src/Tests/Migrate/d7/MigrateUserTest.php
@@ -29,15 +29,7 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
    */
   protected function setUp() {
     parent::setUp();
-
-    // Prepare to migrate user pictures as well.
-    $this->installEntitySchema('file');
-    $this->executeMigrations([
-      'user_picture_field',
-      'user_picture_field_instance',
-      'd7_user_role',
-      'd7_user',
-    ]);
+    $this->migrateUsers(TRUE);
   }
 
   /**
