diff --git a/core/modules/config/config.module b/core/modules/config/config.module
index 05f4b6d..30456b6 100644
--- a/core/modules/config/config.module
+++ b/core/modules/config/config.module
@@ -15,7 +15,7 @@ function config_help($route_name, RouteMatchInterface $route_match) {
     case 'help.page.config':
       $output = '';
       $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Configuration manager module provides a user interface for importing and exporting configuration changes; i.e., for staging configuration data between multiple instances of this web site. For more information, see the online handbook entry for <a href="!url">Configuration manager module</a>', array(
+      $output .= '<p>' . t('The Configuration Manager module provides a user interface for importing and exporting configuration changes; i.e., for staging configuration data between multiple instances of this web site. For more information, see the online handbook entry for <a href="!url">Configuration manager module</a>', array(
         '!url' => 'https://www.drupal.org/documentation/administer/config',
       )) . '</p>';
       return $output;
diff --git a/core/modules/system/src/Tests/Module/InstallUninstallTest.php b/core/modules/system/src/Tests/Module/InstallUninstallTest.php
index 125b754..10ced5b 100644
--- a/core/modules/system/src/Tests/Module/InstallUninstallTest.php
+++ b/core/modules/system/src/Tests/Module/InstallUninstallTest.php
@@ -37,32 +37,62 @@ public function testInstallUninstall() {
     // Try to install and uninstall book, toolbar modules and its dependencies.
     $all_modules = system_rebuild_module_data();
 
+    // Test help on required modules, but do not test uninstalling.
+    $required_modules = array_filter($all_modules, function ($module) {
+      if (!empty($module->info['required']) || $module->status == TRUE) {
+        if ($module->info['package'] != 'Testing' && empty($module->info['hidden'])) {
+          return TRUE;
+        }
+      }
+      return FALSE;
+    });
+
+    $required_modules['help'] = $all_modules['help'];
+
+    // Test uninstalling without hidden, required, and already enabled modules.
     $all_modules = array_filter($all_modules, function ($module) {
-      // Filter hidden, required and already enabled modules.
       if (!empty($module->info['hidden']) || !empty($module->info['required']) || $module->status == TRUE || $module->info['package'] == 'Testing') {
         return FALSE;
       }
       return TRUE;
     });
 
-    // Go through each module in the list and try to install it (unless it was
-    // already installed automatically due to a dependency).
-    $automatically_installed = array();
+    // There are a couple of modules with special needs before they can be
+    // uninstalled. Make special methods for them.
+    $pre_uninstall = array(
+      'forum' => 'preUninstallForum',
+    );
+
+    // Install the Help module, and verify it installed successfully.
+    unset($all_modules['help']);
+    $this->assertModules(array('help'), FALSE);
+    $this->assertModuleTablesDoNotExist('help');
+    $edit = array();
+    $package = $required_modules['help']->info['package'];
+    $edit["modules[$package][help][enable]"] = TRUE;
+    $this->drupalPostForm('admin/modules', $edit, t('Save configuration'));
+    $this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
+    $this->assertText(t('hook_modules_installed fired for help'));
+    $this->assertModules(array('help'), TRUE);
+    $this->assertModuleTablesExist('help');
+    $this->assertModuleConfig('help');
+
+    // Test help for the required modules.
+    foreach ($required_modules as $name => $module) {
+      $this->assertHelp($name, $module->info['name']);
+    }
+
+    // Go through each module in the list and try to install and uninstall
+    // it with its dependencies.
     while (list($name, $module) = each($all_modules)) {
-      // Skip modules that have been automatically installed.
-      if (in_array($name, $automatically_installed)) {
-        continue;
-      }
+      $this->rebuildContainer();
+      $was_installed_list = \Drupal::moduleHandler()->getModuleList();
 
       // Start a list of modules that we expect to be installed this time.
       $modules_to_install = array($name);
       foreach (array_keys($module->requires) as $dependency) {
-        if (isset($all_modules[$dependency]) && !in_array($dependency, $automatically_installed)) {
+        if (isset($all_modules[$dependency])) {
           $modules_to_install[] = $dependency;
-
-          // Add any potential dependency of this module to the list of modules we
-          // expect to be automatically installed.
-          $automatically_installed[] = $dependency;
         }
       }
 
@@ -98,36 +128,49 @@ public function testInstallUninstall() {
         $this->assertLogMessage('system', "%module module installed.", array('%module' => $module_to_install), RfcLogLevel::INFO);
       }
 
-      // Uninstall the original module, and check appropriate
-      // hooks, tables, and log messages. (Later, we'll go back and do the
-      // same thing for modules that were enabled automatically.)
-      $this->assertSuccessfullUninstall($name, $package);
-    }
+      // Verify the help page.
+      $this->assertHelp($name, $module->info['name']);
 
-    // Go through all modules that were automatically installed, and try to
-    // uninstall them one by one.
-    while ($automatically_installed) {
-      $initial_count = count($automatically_installed);
-      foreach ($automatically_installed as $name) {
-        $package = $all_modules[$name]->info['package'];
-        // If the module can't be uninstalled due to dependencies, skip it and
-        // try again the next time. Otherwise, try to uninstall it.
-        $this->drupalGet('admin/modules/uninstall');
-        $disabled_checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="uninstall[' . $name . ']"]');
-        if (empty($disabled_checkbox)) {
-          $automatically_installed = array_diff($automatically_installed, array($name));
-          $this->assertSuccessfullUninstall($name, $package);
-        }
+      // Uninstall the original module, plus everything else that was installed
+      // with it.
+      $this->rebuildContainer();
+      if (isset($pre_uninstall[$name])) {
+        call_user_func(array($this, $pre_uninstall[$name]));
       }
-      $final_count = count($automatically_installed);
-      // If all checkboxes were disabled, something is really wrong with the
-      // test. Throw a failure and avoid an infinite loop.
-      if ($initial_count == $final_count) {
-        $this->fail('Remaining modules could not be disabled.');
-        break;
+      $now_installed_list = \Drupal::moduleHandler()->getModuleList();
+      $added_modules = array_diff(array_keys($now_installed_list), array_keys($was_installed_list));
+      while ($added_modules) {
+        $initial_count = count($added_modules);
+        foreach ($added_modules as $to_uninstall) {
+          // See if we can currently uninstall this module (if its dependencies
+          // have been uninstalled), and do so if we can.
+          $this->drupalGet('admin/modules/uninstall');
+          $field_name = "uninstall[$to_uninstall]";
+          $has_checkbox = $this->xpath('//input[@type="checkbox" and @name="' . $field_name . '"]');
+          $disabled = $this->xpath('//input[@type="checkbox" and @name="' . $field_name . '" and @disabled="disabled"]');
+
+          if (!empty($has_checkbox) && empty($disabled)) {
+            // This one is eligible for being uninstalled.
+            $package = $all_modules[$to_uninstall]->info['package'];
+            $this->assertSuccessfullUninstall($to_uninstall, $package);
+            $added_modules = array_diff($added_modules, array($to_uninstall));
+          }
+        }
+
+        // If we were not able to find a module to uninstall, fail and exit the
+        // loop.
+        $final_count = count($added_modules);
+        if ($initial_count == $final_count) {
+          $this->fail('Remaining modules could not be disabled for ' . $name);
+          break;
+        }
       }
     }
 
+    // Uninstall the help module and put it back into the list of modules.
+    $all_modules['help'] = $required_modules['help'];
+    $this->assertSuccessfullUninstall('help', $required_modules['help']->info['package']);
+
     // Now that all modules have been tested, go back and try to enable them
     // all again at once. This tests two things:
     // - That each module can be successfully enabled again after being
@@ -153,15 +196,6 @@ public function testInstallUninstall() {
    */
   protected function assertSuccessfullUninstall($module, $package = 'Core') {
     $edit = array();
-    if ($module == 'forum') {
-      // Forum cannot be uninstalled until all of the content entities related
-      // to it have been deleted.
-      $vid = $this->config('forum.settings')->get('vocabulary');
-      $terms = entity_load_multiple_by_properties('taxonomy_term', ['vid' => $vid]);
-      foreach ($terms as $term) {
-        $term->delete();
-      }
-    }
     $edit['uninstall[' . $module . ']'] = TRUE;
     $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
     $this->drupalPostForm(NULL, NULL, t('Uninstall'));
@@ -181,4 +215,35 @@ protected function assertSuccessfullUninstall($module, $package = 'Core') {
     $this->assertNoModuleConfig($module);
   }
 
+  /**
+   * Verifies a module's help.
+   *
+   * Verifies that the module help page from hook_help() exists and can be
+   * displayed, and that it contains the phrase "Foo Bar module", where "Foo
+   * Bar" is the name of the module from the .info.yml file.
+   *
+   * @param string $module
+   *   Machine name of the module to verify.
+   * @param array $info
+   *   Human-readable name of the module.
+   */
+  protected function assertHelp($module, $name) {
+    $this->drupalGet('admin/help/' . $module);
+    $this->assertResponse(200, "Help for $module displayed successfully");
+    $this->assertText($name . ' module', "'$name module' is on the help page for $module");
+  }
+
+  /**
+   * Deletes forum taxonomy terms, so Forum can be uninstalled.
+   */
+  protected function preUninstallForum() {
+    // There only should be a 'General discussion' term in the 'forums'
+    // vocabulary, but just delete any terms there in case the name changes.
+    $query = \Drupal::entityQuery('taxonomy_term');
+    $query->condition('vid', 'forums');
+    $ids = $query->execute();
+    $storage = \Drupal::entityManager()->getStorage('taxonomy_term');
+    $terms = $storage->loadMultiple($ids);
+    $storage->delete($terms);
+  }
 }
