diff --git a/core/modules/field/tests/modules/field_test/field_test.entity.inc b/core/modules/field/tests/modules/field_test/field_test.entity.inc
index 3d4b0fabdb16fe65f635b45f4e5f7a9c0fb27d85..b6aa86e6850f42e1fee4d4e809a80cf13f6e3d75 100644
--- a/core/modules/field/tests/modules/field_test/field_test.entity.inc
+++ b/core/modules/field/tests/modules/field_test/field_test.entity.inc
@@ -43,6 +43,8 @@ function field_test_entity_info_translatable($entity_type = NULL, $translatable
 
 /**
  * Form combining two separate entities.
+ *
+ * @deprecated Use \Drupal\field_test\Form\FieldTestForm::testEntityNestedForm()
  */
 function field_test_entity_nested_form($form, &$form_state, $entity_1, $entity_2) {
   // First entity.
diff --git a/core/modules/field/tests/modules/field_test/field_test.module b/core/modules/field/tests/modules/field_test/field_test.module
index a95d4573da78159e4790331a1244feb2062b0cfe..992e6ef95e2d4d8893b4d0787ce547dd9e09bdb6 100644
--- a/core/modules/field/tests/modules/field_test/field_test.module
+++ b/core/modules/field/tests/modules/field_test/field_test.module
@@ -43,10 +43,7 @@ function field_test_menu() {
   $items = array();
   $items['test-entity/nested/%entity_test/%entity_test'] = array(
     'title' => 'Nested entity form',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('field_test_entity_nested_form', 2, 3),
-    'access arguments' => array('administer entity_test content'),
-    'type' => MENU_NORMAL_ITEM,
+    'route_name' => 'field_test.entity_nested_form',
   );
 
   return $items;
diff --git a/core/modules/field/tests/modules/field_test/field_test.routing.yml b/core/modules/field/tests/modules/field_test/field_test.routing.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b7ba00cb36879c8782ba14944d721daa569df553
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/field_test.routing.yml
@@ -0,0 +1,13 @@
+field_test.entity_nested_form:
+  path: '/test-entity/nested/{entity_1}/{entity_2}'
+  defaults:
+    _title: 'Nested entity form'
+    _content: '\Drupal\field_test\Form\FieldTestForm::testEntityNestedForm'
+  options:
+    parameters:
+      entity_1:
+        type: 'entity:entity_test'
+      entity_2:
+        type: 'entity:entity_test'
+  requirements:
+    _permission: 'administer entity_test content'
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Form/FieldTestForm.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Form/FieldTestForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..8c9e913e5b2e84dcc8780bda7054c3b3c87dcacd
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Form/FieldTestForm.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field_test\Form\FieldTestForm.
+ */
+
+namespace Drupal\field_test\Form;
+
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Provides a form for field_test routes.
+ */
+class FieldTestForm {
+
+  /**
+   * @todo Remove field_test_entity_nested_form().
+   */
+  public function testEntityNestedForm(EntityInterface $entity_1, EntityInterface $entity_2) {
+    module_load_include('entity.inc', 'field_test');
+    return drupal_get_form('field_test_entity_nested_form', $entity_1, $entity_2);
+  }
+
+}
diff --git a/core/modules/file/tests/file_module_test.info.yml b/core/modules/file/tests/file_module_test/file_module_test.info.yml
similarity index 100%
rename from core/modules/file/tests/file_module_test.info.yml
rename to core/modules/file/tests/file_module_test/file_module_test.info.yml
diff --git a/core/modules/file/tests/file_module_test.module b/core/modules/file/tests/file_module_test/file_module_test.module
similarity index 86%
rename from core/modules/file/tests/file_module_test.module
rename to core/modules/file/tests/file_module_test/file_module_test.module
index f76488ceefdc0643da9d0568296ff9df52af5560..592bcaab0905d3c9eff23506687c330b73ead9ea 100644
--- a/core/modules/file/tests/file_module_test.module
+++ b/core/modules/file/tests/file_module_test/file_module_test.module
@@ -9,28 +9,14 @@
 use Drupal\file\Entity\File;
 use Drupal\field\FieldInterface;
 
-/**
- * Implements hook_menu().
- */
-function file_module_test_menu() {
-  $items = array();
-
-  $items['file/test'] = array(
-    'title' => 'Managed file test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('file_module_test_form'),
-    'access arguments' => array('access content'),
-  );
-
-  return $items;
-}
-
 /**
  * Form constructor for testing a 'managed_file' element.
  *
  * @see file_module_test_menu()
  * @see file_module_test_form_submit()
  * @ingroup forms
+ *
+ * @deprecated Use \Drupal\file_module_test\Form\FileModuleTestForm::managedFileTest()
  */
 function file_module_test_form($form, &$form_state, $tree = TRUE, $extended = TRUE, $multiple = FALSE, $default_fids = NULL) {
   $form['#tree'] = (bool) $tree;
diff --git a/core/modules/file/tests/file_module_test/file_module_test.routing.yml b/core/modules/file/tests/file_module_test/file_module_test.routing.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5238cc87130d05bb965fd9f521b674b8a2b6b25b
--- /dev/null
+++ b/core/modules/file/tests/file_module_test/file_module_test.routing.yml
@@ -0,0 +1,10 @@
+file_module_test.managed_test:
+  path: '/file/test/{tree}/{extended}/{multiple}/{default_fids}'
+  defaults:
+    _content: '\Drupal\file_module_test\Form\FileModuleTestForm::managedFileTest'
+    tree: TRUE
+    extended: TRUE
+    multiple: FALSE
+    default_fids: NULL
+  requirements:
+    _permission: 'access content'
diff --git a/core/modules/file/tests/file_module_test/lib/Drupal/file_module_test/Form/FileModuleTestForm.php b/core/modules/file/tests/file_module_test/lib/Drupal/file_module_test/Form/FileModuleTestForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..fdd3cdbcb866d52b061bdfbf6ee9ebfdd166e1e9
--- /dev/null
+++ b/core/modules/file/tests/file_module_test/lib/Drupal/file_module_test/Form/FileModuleTestForm.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\file_module_test\Form\FileModuleTestForm.
+ */
+
+namespace Drupal\file_module_test\Form;
+
+/**
+ * Temporary form controller for file_module_test module.
+ */
+class FileModuleTestForm {
+
+  /**
+   * @todo Remove file_module_test_form().
+   */
+  public function managedFileTest($tree, $extended, $multiple, $default_fids) {
+    return drupal_get_form('file_module_test_form', $tree, $extended, $multiple, $default_fids);
+  }
+
+}
diff --git a/core/modules/language/tests/language_elements_test/language_elements_test.module b/core/modules/language/tests/language_elements_test/language_elements_test.module
index 14d8927ab3cdbbadb453b75a5eb3c4df9c71e6f6..a85b7f37520d73c47eb9a7668501c1ccfe83601e 100644
--- a/core/modules/language/tests/language_elements_test/language_elements_test.module
+++ b/core/modules/language/tests/language_elements_test/language_elements_test.module
@@ -5,27 +5,6 @@
  * Mock module for language form elements test.
  */
 
-/**
- * Implements hook_menu().
- */
-function language_elements_test_menu() {
-  $items['language-tests/language_configuration_element'] = array(
-    'title' => 'Language configuration form element',
-    'type' => MENU_CALLBACK,
-    'access callback' => TRUE,
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('language_elements_configuration_element'),
-  );
-  $items['language-tests/language_configuration_element_test'] = array(
-    'title' => 'Language configuration form element',
-    'type' => MENU_CALLBACK,
-    'access callback' => TRUE,
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('language_elements_configuration_element_test'),
-  );
-  return $items;
-}
-
 /**
  * A form containing a language configuration element.
  */
diff --git a/core/modules/language/tests/language_elements_test/language_elements_test.routing.yml b/core/modules/language/tests/language_elements_test/language_elements_test.routing.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5a5698cad65c03309bd9ce3a70d662b317568be1
--- /dev/null
+++ b/core/modules/language/tests/language_elements_test/language_elements_test.routing.yml
@@ -0,0 +1,15 @@
+language_elements_test.config_element:
+  path: '/language-tests/language_configuration_element'
+  defaults:
+    _content: '\Drupal\language_elements_test\Form\LanguageElementsTestForm::configFormElement'
+    _title: 'Language configuration form element'
+  requirements:
+    _access: 'TRUE'
+
+language_elements_test.config_element_test:
+  path: '/language-tests/language_configuration_element_test'
+  defaults:
+    _content: '\Drupal\language_elements_test\Form\LanguageElementsTestForm::configFormElementTest'
+    _title: 'Language configuration form element'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/language/tests/language_elements_test/lib/Drupal/language_elements_test/Form/LanguageElementsTestForm.php b/core/modules/language/tests/language_elements_test/lib/Drupal/language_elements_test/Form/LanguageElementsTestForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..15dd084d4f706236680d708e31a137e447c16950
--- /dev/null
+++ b/core/modules/language/tests/language_elements_test/lib/Drupal/language_elements_test/Form/LanguageElementsTestForm.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language_elements_test\Form\LanguageElementsTestForm.
+ */
+
+namespace Drupal\language_elements_test\Form;
+
+/**
+ * Controller routines for language_elements_test routes.
+ */
+class LanguageElementsTestForm {
+
+  /**
+   * Wraps language_elements_configuration_element().
+   *
+   * @todo Remove language_elements_configuration_element().
+   */
+  public function configFormElement() {
+    return drupal_get_form('language_elements_configuration_element');
+  }
+
+  /**
+   * Wraps language_element_tests_configuration_element_test().
+   *
+   * @todo Remove language_element_tests_configuration_element_test().
+   */
+  public function configFormElementTest() {
+    return drupal_get_form('language_elements_configuration_element_test');
+  }
+
+}
+
diff --git a/core/modules/search/tests/modules/search_embedded_form/lib/Drupal/search_embedded_form/Form/SearchEmbeddedForm.php b/core/modules/search/tests/modules/search_embedded_form/lib/Drupal/search_embedded_form/Form/SearchEmbeddedForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..59a5921ce86c63508f93872d6ec0bd507f5323f1
--- /dev/null
+++ b/core/modules/search/tests/modules/search_embedded_form/lib/Drupal/search_embedded_form/Form/SearchEmbeddedForm.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\search_embedded_form\Form\SearchEmbeddedForm.
+ */
+
+namespace Drupal\search_embedded_form\Form;
+
+/**
+ * Temporary form controller for search_embedded_form module.
+ */
+class SearchEmbeddedForm {
+
+  /**
+   * @todo Remove search_embedded_form_form().
+   */
+  public function testEmbeddedForm() {
+    return drupal_get_form('search_embedded_form_form');
+  }
+
+}
diff --git a/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.module b/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.module
index 680322a0c9a4f34a269c3b1eaaae3d0e24c319f5..de69a95f10feadcf0b9350efb279257b43150067 100644
--- a/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.module
+++ b/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.module
@@ -9,25 +9,12 @@
  * individual product (node) listed in the search results.
  */
 
-/**
-  * Implements hook_menu().
-  */
-function search_embedded_form_menu() {
-  $items['search_embedded_form'] = array(
-    'title' => 'Search_Embed_Form',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('search_embedded_form_form'),
-    'access arguments' => array('search content'),
-    'type' => MENU_CALLBACK,
-  );
-
-  return $items;
-}
-
 /**
  * Form constructor for embedding search results for testing.
  *
  * @see search_embedded_form_form_submit().
+ *
+ * @deprecated Use \Drupal\search_embedded_form\Form\SearchEmbeddedForm::testEmbeddedForm()
  */
 function search_embedded_form_form($form, &$form_state) {
   $count = \Drupal::config('search_embedded_form.settings')->get('submitted');
diff --git a/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.routing.yml b/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.routing.yml
new file mode 100644
index 0000000000000000000000000000000000000000..20615ec3ba76b23d6a4080398545ad63ca527499
--- /dev/null
+++ b/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.routing.yml
@@ -0,0 +1,7 @@
+search_embedded_form.test_embedded_form:
+  path: '/search_embedded_form'
+  defaults:
+    _title: 'Search_Embed_Form'
+    _content: '\Drupal\search_embedded_form\Form\SearchEmbeddedForm::testEmbeddedForm'
+  requirements:
+    _permission: 'search content'
diff --git a/core/modules/system/lib/Drupal/system/Tests/Batch/ProcessingTest.php b/core/modules/system/lib/Drupal/system/Tests/Batch/ProcessingTest.php
index b452e69120454958a6fb23b46686077b48da5ad6..de63b730f492578abc4b625f85c73f865a837132 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Batch/ProcessingTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Batch/ProcessingTest.php
@@ -46,34 +46,34 @@ function testBatchNoForm() {
   function testBatchForm() {
     // Batch 0: no operation.
     $edit = array('batch' => 'batch_0');
-    $this->drupalPostForm('batch-test/simple', $edit, 'Submit');
+    $this->drupalPostForm('batch-test', $edit, 'Submit');
     $this->assertBatchMessages($this->_resultMessages('batch_0'), 'Batch with no operation performed successfully.');
     $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.');
 
     // Batch 1: several simple operations.
     $edit = array('batch' => 'batch_1');
-    $this->drupalPostForm('batch-test/simple', $edit, 'Submit');
+    $this->drupalPostForm('batch-test', $edit, 'Submit');
     $this->assertBatchMessages($this->_resultMessages('batch_1'), 'Batch with simple operations performed successfully.');
     $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_1'), 'Execution order was correct.');
     $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.');
 
     // Batch 2: one multistep operation.
     $edit = array('batch' => 'batch_2');
-    $this->drupalPostForm('batch-test/simple', $edit, 'Submit');
+    $this->drupalPostForm('batch-test', $edit, 'Submit');
     $this->assertBatchMessages($this->_resultMessages('batch_2'), 'Batch with multistep operation performed successfully.');
     $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_2'), 'Execution order was correct.');
     $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.');
 
     // Batch 3: simple + multistep combined.
     $edit = array('batch' => 'batch_3');
-    $this->drupalPostForm('batch-test/simple', $edit, 'Submit');
+    $this->drupalPostForm('batch-test', $edit, 'Submit');
     $this->assertBatchMessages($this->_resultMessages('batch_3'), 'Batch with simple and multistep operations performed successfully.');
     $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_3'), 'Execution order was correct.');
     $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.');
 
     // Batch 4: nested batch.
     $edit = array('batch' => 'batch_4');
-    $this->drupalPostForm('batch-test/simple', $edit, 'Submit');
+    $this->drupalPostForm('batch-test', $edit, 'Submit');
     $this->assertBatchMessages($this->_resultMessages('batch_4'), 'Nested batch performed successfully.');
     $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_4'), 'Execution order was correct.');
     $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.');
diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/FileInclusionTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/FileInclusionTest.php
deleted file mode 100644
index 369806709191a1ba4fdf945ff8ed0708ffb9fd74..0000000000000000000000000000000000000000
--- a/core/modules/system/lib/Drupal/system/Tests/Form/FileInclusionTest.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\system\Tests\Form\FileInclusionTest.
- */
-
-namespace Drupal\system\Tests\Form;
-
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Tests form API file inclusion.
- */
-class FileInclusionTest extends WebTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('form_test');
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Form API file inclusion',
-      'description' => 'Tests form API file inclusion.',
-      'group' => 'Form API',
-    );
-  }
-
-  /**
-   * Tests loading an include specified in hook_menu().
-   */
-  function testLoadMenuInclude() {
-    $this->drupalPostAjaxForm('form-test/load-include-menu', array(), array('op' => t('Save')), 'system/ajax', array(), array(), 'form-test-load-include-menu');
-    $this->assertText('Submit callback called.');
-  }
-
-  /**
-   * Tests loading a custom specified include.
-   */
-  function testLoadCustomInclude() {
-    $this->drupalPostForm('form-test/load-include-custom', array(), t('Save'));
-    $this->assertText('Submit callback called.');
-  }
-}
diff --git a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module
index 175d593534df2fe2ce02f1659831ced8bc83fb0b..31888d705606e74e1365198f39784c6b5586a756 100644
--- a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module
+++ b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module
@@ -9,40 +9,10 @@
 use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\ajax_forms_test\Callbacks;
 
-/**
- * Implements hook_menu().
- */
-function ajax_forms_test_menu() {
-  $items = array();
-  $items['ajax_forms_test_get_form'] = array(
-    'title' => 'AJAX forms simple form test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('ajax_forms_test_simple_form'),
-    'access callback' => TRUE,
-  );
-  $items['ajax_forms_test_ajax_commands_form'] = array(
-    'title' => 'AJAX forms AJAX commands test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('ajax_forms_test_ajax_commands_form'),
-    'access callback' => TRUE,
-  );
-  $items['ajax_validation_test'] = array(
-    'title' => 'AJAX Validation Test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('ajax_forms_test_validation_form'),
-    'access callback' => TRUE,
-  );
-  $items['ajax_forms_test_lazy_load_form'] = array(
-    'title' => 'AJAX forms lazy load test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('ajax_forms_test_lazy_load_form'),
-    'access callback' => TRUE,
-  );
-  return $items;
-}
-
 /**
  * Tests form_state['values'] during callback.
+ *
+ * @deprecated Use \Drupal\ajax_forms_test\Form\AjaxFormsTestForm::getForm()
  */
 function ajax_forms_test_simple_form($form, &$form_state) {
   $object = new Callbacks();
@@ -95,6 +65,8 @@ function ajax_forms_test_simple_form($form, &$form_state) {
 
 /**
  * Form constructor for the Ajax Command display form.
+ *
+ * @deprecated Use \Drupal\ajax_forms_test\Form\AjaxFormsTestForm::commandsForm()
  */
 function ajax_forms_test_ajax_commands_form($form, &$form_state) {
   $form = array();
@@ -462,6 +434,8 @@ function ajax_forms_test_advanced_commands_settings_with_merging_callback($form,
  * be able to trigger without causing validation of the "required_field".
  *
  * @see ajax_forms_test_validation_form_submit()
+ *
+ * @deprecated Use \Drupal\ajax_forms_test\Form\AjaxFormsTestForm::validationForm()
  */
 function ajax_forms_test_validation_form($form, &$form_state) {
 
@@ -534,6 +508,8 @@ function ajax_forms_test_validation_number_form_callback($form, $form_state) {
 
 /**
  * Form builder: Builds a form that triggers a simple AJAX callback.
+ *
+ * @deprecated Use \Drupal\ajax_forms_test\Form\AjaxFormsTestForm::lazyLoadForm()
  */
 function ajax_forms_test_lazy_load_form($form, &$form_state) {
   // We attach a JavaScript setting, so that one of the generated AJAX commands
diff --git a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a01db363f57b94aa892bbe78952aca50b1829795
--- /dev/null
+++ b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml
@@ -0,0 +1,31 @@
+ajax_forms_test.get_form:
+  path: '/ajax_forms_test_get_form'
+  defaults:
+    _title: 'AJAX forms simple form test'
+    _content: '\Drupal\ajax_forms_test\Form\AjaxFormsTestForm::getForm'
+  requirements:
+    _access: 'TRUE'
+
+ajax_forms_test.commands_form:
+  path: '/ajax_forms_test_ajax_commands_form'
+  defaults:
+    _title: 'AJAX forms AJAX commands test'
+    _content: '\Drupal\ajax_forms_test\Form\AjaxFormsTestForm::commandsForm'
+  requirements:
+    _access: 'TRUE'
+
+ajax_forms_test.validation_test:
+  path: '/ajax_validation_test'
+  defaults:
+    _title: 'AJAX Validation Test'
+    _content: '\Drupal\ajax_forms_test\Form\AjaxFormsTestForm::validationForm'
+  requirements:
+    _access: 'TRUE'
+
+ajax_forms_test.lazy_load_form:
+  path: '/ajax_forms_test_lazy_load_form'
+  defaults:
+    _title: 'AJAX forms lazy load test'
+    _content: '\Drupal\ajax_forms_test\Form\AjaxFormsTestForm::lazyLoadForm'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/ajax_forms_test/lib/Drupal/ajax_forms_test/Form/AjaxFormsTestForm.php b/core/modules/system/tests/modules/ajax_forms_test/lib/Drupal/ajax_forms_test/Form/AjaxFormsTestForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a231ee9a8e8901089868d046e78dbaf6dcb0a41
--- /dev/null
+++ b/core/modules/system/tests/modules/ajax_forms_test/lib/Drupal/ajax_forms_test/Form/AjaxFormsTestForm.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\ajax_forms_test\Form\AjaxFormsTestForm.
+ */
+
+namespace Drupal\ajax_forms_test\Form;
+
+/**
+ * Temporary form controller for ajax_forms_test module.
+ */
+class AjaxFormsTestForm {
+
+  /**
+   * @todo Remove ajax_forms_test_simple_form().
+   */
+  public function getForm() {
+    return drupal_get_form('ajax_forms_test_simple_form');
+  }
+
+  /**
+   * @todo Remove ajax_forms_test_ajax_commands_form().
+   */
+  public function commandsForm() {
+    return drupal_get_form('ajax_forms_test_ajax_commands_form');
+  }
+
+  /**
+   * @todo Remove ajax_forms_test_validation_form().
+   */
+  public function validationForm() {
+    return drupal_get_form('ajax_forms_test_validation_form');
+  }
+
+  /**
+   * @todo Remove ajax_forms_test_lazy_load_form().
+   */
+  public function lazyLoadForm() {
+    return drupal_get_form('ajax_forms_test_lazy_load_form');
+  }
+
+}
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.module b/core/modules/system/tests/modules/batch_test/batch_test.module
index 3f7ffc7b7fe2f41b1f8f82429fd138f136224260..ff0e37fb4c1827745821d2a25a763f06063b6a44 100644
--- a/core/modules/system/tests/modules/batch_test/batch_test.module
+++ b/core/modules/system/tests/modules/batch_test/batch_test.module
@@ -13,9 +13,7 @@ function batch_test_menu() {
 
   $items['batch-test'] = array(
     'title' => 'Batch test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('batch_test_simple_form'),
-    'access callback' => TRUE,
+    'route_name' => 'batch_test.test_form',
   );
   // Simple form: one submit handler, setting a batch.
   $items['batch-test/simple'] = array(
@@ -26,18 +24,14 @@ function batch_test_menu() {
   // Multistep form: two steps, each setting a batch.
   $items['batch-test/multistep'] = array(
     'title' => 'Multistep',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('batch_test_multistep_form'),
-    'access callback' => TRUE,
+    'route_name' => 'batch_test.multistep',
     'type' => MENU_LOCAL_TASK,
     'weight' => 1,
   );
   // Chained form: four submit handlers, several of which set a batch.
   $items['batch-test/chained'] = array(
     'title' => 'Chained',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('batch_test_chained_form'),
-    'access callback' => TRUE,
+    'route_name' => 'batch_test.chained',
     'type' => MENU_LOCAL_TASK,
     'weight' => 2,
   );
@@ -80,6 +74,8 @@ function batch_test_menu() {
  * Form constructor for a batch selection form.
  *
  * @see batch_test_simple_form_submit()
+ *
+ * @deprecated Use \Drupal\batch_test\Form\BatchTestForm::testForm()
  */
 function batch_test_simple_form() {
   $form['batch'] = array(
@@ -120,6 +116,8 @@ function batch_test_simple_form_submit($form, &$form_state) {
  * Form constructor for a multistep form.
  *
  * @see batch_test_multistep_form_submit()
+ *
+ * @deprecated Use \Drupal\batch_test\Form\BatchTestForm::testMultistepForm()
  */
 function batch_test_multistep_form($form, &$form_state) {
   if (empty($form_state['storage']['step'])) {
@@ -170,6 +168,8 @@ function batch_test_multistep_form_submit($form, &$form_state) {
  * @see batch_test_chained_form_submit_3()
  * @see batch_test_chained_form_submit_3()
  * @see batch_test_chained_form_submit_4()
+ *
+ * @deprecated Use \Drupal\batch_test\Form\BatchTestForm::testChainedForm()
  */
 function batch_test_chained_form() {
   // This value is used to test that $form_state persists through batched
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.routing.yml b/core/modules/system/tests/modules/batch_test/batch_test.routing.yml
index 8199f03d0d1b3ed44fba58516e6561303bf7b203..afdba91820e76d81a2f7b624d59969e6f2761165 100644
--- a/core/modules/system/tests/modules/batch_test/batch_test.routing.yml
+++ b/core/modules/system/tests/modules/batch_test/batch_test.routing.yml
@@ -31,6 +31,30 @@ batch_test.no_form:
   requirements:
     _access: 'TRUE'
 
+batch_test.test_form:
+  path: '/batch-test'
+  defaults:
+    _content: '\Drupal\batch_test\Form\BatchTestForm::testForm'
+    _title: 'Batch test'
+  requirements:
+    _access: 'TRUE'
+
+batch_test.multistep:
+  path: '/batch-test/multistep'
+  defaults:
+    _content: '\Drupal\batch_test\Form\BatchTestForm::testMultistepForm'
+    _title: 'Multistep'
+  requirements:
+    _access: 'TRUE'
+
+batch_test.chained:
+  path: '/batch-test/chained'
+  defaults:
+    _content: '\Drupal\batch_test\Form\BatchTestForm::testChainedForm'
+    _title: 'Chained'
+  requirements:
+    _access: 'TRUE'
+
 batch_test.programmatic:
   path: '/batch-test/programmatic/{value}'
   defaults:
diff --git a/core/modules/system/tests/modules/batch_test/lib/Drupal/batch_test/Form/BatchTestForm.php b/core/modules/system/tests/modules/batch_test/lib/Drupal/batch_test/Form/BatchTestForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..af9dbc95771afc5556ba0c25e405f99529fc4d6e
--- /dev/null
+++ b/core/modules/system/tests/modules/batch_test/lib/Drupal/batch_test/Form/BatchTestForm.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\batch_test\Form\BatchTestForm.
+ */
+
+namespace Drupal\batch_test\Form;
+
+/**
+ * Temporary form controller for batch_test module.
+ */
+class BatchTestForm {
+
+  /**
+   * @todo Remove batch_test_simple_form().
+   */
+  public function testForm() {
+    return drupal_get_form('batch_test_simple_form');
+  }
+
+  /**
+   * @todo Remove batch_test_multistep_form().
+   */
+  public function testMultistepForm() {
+    return drupal_get_form('batch_test_multistep_form');
+  }
+
+  /**
+   * @todo Remove batch_test_chained_form().
+   */
+  public function testChainedForm() {
+    return drupal_get_form('batch_test_chained_form');
+  }
+
+}
diff --git a/core/modules/system/tests/modules/database_test/database_test.module b/core/modules/system/tests/modules/database_test/database_test.module
index 19eb6ed233796257d3337c13886f940ab54b6ece..8710c5535817736c4c3f530ed6dc70334ec8e93c 100644
--- a/core/modules/system/tests/modules/database_test/database_test.module
+++ b/core/modules/system/tests/modules/database_test/database_test.module
@@ -45,18 +45,6 @@ function database_test_query_database_test_alter_remove_range_alter(AlterableInt
   $query->range();
 }
 
-/**
- * Implements hook_menu().
- */
-function database_test_menu() {
-  $items['database_test/tablesort_default_sort'] = array(
-    'access callback' => TRUE,
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('database_test_theme_tablesort'),
-  );
-  return $items;
-}
-
 /**
  * Runs db_query_temporary() and outputs the table name and its number of rows.
  *
@@ -195,6 +183,8 @@ function database_test_tablesort_first() {
 
 /**
  * Outputs a form without setting a header sort.
+ *
+ * @deprecated \Drupal\database_test\Form\DatabaseTestForm::testTablesortDefaultSort()
  */
 function database_test_theme_tablesort($form, &$form_state) {
   $header = array(
diff --git a/core/modules/system/tests/modules/database_test/database_test.routing.yml b/core/modules/system/tests/modules/database_test/database_test.routing.yml
index 46fa58060992838955e9cd853d984e7ce3daf4e1..a6ca5dedfc5a7df71a96289ca6c1aab95fdca0c2 100644
--- a/core/modules/system/tests/modules/database_test/database_test.routing.yml
+++ b/core/modules/system/tests/modules/database_test/database_test.routing.yml
@@ -32,3 +32,10 @@ database_test.tablesort_first:
     _content: '\Drupal\database_test\Controller\DatabaseTestController::testTablesortFirst'
   requirements:
     _access: 'TRUE'
+
+database_test.tablesort_default_sort:
+  path: '/database_test/tablesort_default_sort'
+  defaults:
+    _content: '\Drupal\database_test\Form\DatabaseTestForm::testTablesortDefaultSort'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/database_test/lib/Drupal/database_test/Form/DatabaseTestForm.php b/core/modules/system/tests/modules/database_test/lib/Drupal/database_test/Form/DatabaseTestForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ec7f5007a3fc6f3c604f71ab1958720685eb594
--- /dev/null
+++ b/core/modules/system/tests/modules/database_test/lib/Drupal/database_test/Form/DatabaseTestForm.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\database_test\Form\DatabaseTestForm.
+ */
+
+namespace Drupal\database_test\Form;
+
+/**
+ * Temporary form controller for database_test module.
+ */
+class DatabaseTestForm {
+
+  /**
+   * @todo Remove database_test_theme_tablesort().
+   */
+  public function testTablesortDefaultSort() {
+    return drupal_get_form('database_test_theme_tablesort');
+  }
+
+}
diff --git a/core/modules/system/tests/modules/form_test/form_test.file.inc b/core/modules/system/tests/modules/form_test/form_test.file.inc
deleted file mode 100644
index f9197ead2a5b1541e1b68748ee1a0deb6104d7ca..0000000000000000000000000000000000000000
--- a/core/modules/system/tests/modules/form_test/form_test.file.inc
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-/**
- * @file
- * An include file to test loading it with the form API.
- */
-
-/**
- * Form constructor for testing FAPI file inclusion of the file specified in
- * hook_menu().
- */
-function form_test_load_include_menu($form, &$form_state) {
-  // Submit the form via Ajax. That way the FAPI has to care about including
-  // the file specified in hook_menu().
-  $ajax_wrapper_id = drupal_html_id('form-test-load-include-menu-ajax-wrapper');
-  $form['ajax_wrapper'] = array(
-    '#markup' => '<div id="' . $ajax_wrapper_id . '"></div>',
-  );
-  $form['button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-    '#submit' => array('form_test_load_include_submit'),
-    '#ajax' => array(
-      'wrapper' => $ajax_wrapper_id,
-      'method' => 'append',
-      'callback' => 'form_test_load_include_menu_ajax',
-    ),
-  );
-  return $form;
-}
-
-/**
- * Submit callback for the form API file inclusion test forms.
- */
-function form_test_load_include_submit($form, $form_state) {
-  drupal_set_message('Submit callback called.');
-}
-
-/**
- * Ajax callback for the file inclusion via menu test.
- */
-function form_test_load_include_menu_ajax($form) {
-  // We don't need to return anything, since #ajax['method'] is 'append', which
-  // does not remove the original #ajax['wrapper'] element, and status messages
-  // are automatically added by the Ajax framework as long as there's a wrapper
-  // element to add them to.
-  return '';
-}
diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module
index 7fe368de76589c3cb7f21e027b6edd9fab5e6cf2..a3d1cd0cff0d4a947616418f6b33fdafbe86982c 100644
--- a/core/modules/system/tests/modules/form_test/form_test.module
+++ b/core/modules/system/tests/modules/form_test/form_test.module
@@ -14,329 +14,6 @@
 use Drupal\Core\Datetime\DrupalDateTime;
 use Symfony\Component\HttpFoundation\JsonResponse;
 
-/**
- * Implements hook_menu().
- */
-function form_test_menu() {
-  $items['form-test/alter'] = array(
-    'title' => 'Form altering test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_alter_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-  $items['form-test/validate'] = array(
-    'title' => 'Form validation handlers test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_validate_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-  $items['form-test/validate-required'] = array(
-    'title' => 'Form #required validation',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_validate_required_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-  $items['form-test/validate-required-no-title'] = array(
-    'title' => 'Form #required validation without #title',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_validate_required_form_no_title'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-  $items['form-test/limit-validation-errors'] = array(
-    'title' => 'Form validation with some error suppression',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_limit_validation_errors_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-  $items['form-test/pattern'] = array(
-    'title' => 'Pattern validation',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_pattern_form'),
-    'access callback' => TRUE,
-  );
-
-  $items['form_test/tableselect/multiple-true'] = array(
-    'title' => 'Tableselect checkboxes test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('_form_test_tableselect_multiple_true_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-  $items['form_test/tableselect/multiple-false'] = array(
-    'title' => 'Tableselect radio button test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('_form_test_tableselect_multiple_false_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-  $items['form_test/tableselect/colspan'] = array(
-    'title' => 'Tableselect colspan test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('_form_test_tableselect_colspan_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-  $items['form_test/tableselect/empty-text'] = array(
-    'title' => 'Tableselect empty text test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('_form_test_tableselect_empty_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-  $items['form_test/tableselect/advanced-select'] = array(
-    'title' => 'Tableselect js_select tests',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('_form_test_tableselect_js_select_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form_test/vertical-tabs'] = array(
-    'title' => 'Vertical tabs tests',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('_form_test_vertical_tabs_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form_test/form-storage'] = array(
-    'title' => 'Form storage test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_storage_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form_test/form-state-values-clean'] = array(
-    'title' => 'Form state values clearance test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_form_state_values_clean_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form_test/form-state-values-clean-advanced'] = array(
-    'title' => 'Form state values clearance advanced test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_form_state_values_clean_advanced_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form-test/checkbox'] = array(
-    'title' => t('Form test'),
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('_form_test_checkbox'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-  $items['form-test/select'] = array(
-    'title' => t('Select'),
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_select'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/empty-select'] = array(
-    'title' => 'Empty Select Element',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_empty_select'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/language_select'] = array(
-    'title' => t('Language Select'),
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_language_select'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/placeholder-text'] = array(
-    'title' => 'Placeholder',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_placeholder_test'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/number'] = array(
-    'title' => 'Number',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_number'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/number/range'] = array(
-    'title' => 'Range',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_number', 'range'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/range']= array(
-    'title' => 'Range',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_range'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/range/invalid'] = array(
-    'title' => 'Invalid range',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_range_invalid'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/color'] = array(
-    'title' => 'Color',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_color'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/checkboxes-radios'] = array(
-    'title' => t('Checkboxes, Radios'),
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_checkboxes_radios'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/email'] = array(
-    'title' => 'E-Mail fields',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_email'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/url'] = array(
-    'title' => t('URL'),
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_url'),
-    'access callback' => TRUE,
-  );
-
-  $items['form-test/disabled-elements'] = array(
-    'title' => t('Form test'),
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('_form_test_disabled_elements'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form-test/input-forgery'] = array(
-    'title' => t('Form test'),
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('_form_test_input_forgery'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form-test/form-rebuild-preserve-values'] = array(
-    'title' => 'Form values preservation during rebuild test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_form_rebuild_preserve_values_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form-test/redirect'] = array(
-    'title' => 'Redirect test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_redirect'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form_test/form-labels'] = array(
-    'title' => 'Form label test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_label_test_form'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form-test/state-persist'] = array(
-    'title' => 'Form state persistence without storage',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_state_persist'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form-test/clicked-button'] = array(
-    'title' => 'Clicked button test',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_clicked_button'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form-test/load-include-menu'] = array(
-    'title' => 'FAPI test loading includes',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_load_include_menu'),
-    'access callback' => TRUE,
-    'file' => 'form_test.file.inc',
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form-test/load-include-custom'] = array(
-    'title' => 'FAPI test loading includes',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_load_include_custom'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-  $items['form-test/checkboxes-zero'] = array(
-    'title' => 'FAPI test involving checkboxes and zero',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_checkboxes_zero'),
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['form-test/required-attribute'] = array(
-    'title' => 'Required',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_required_attribute'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/button-class'] = array(
-    'title' => 'Button class testing',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_button_class'),
-    'access callback' => TRUE,
-  );
-
-  $items['form-test/group-details'] = array(
-    'title' => 'Group details testing',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_group_details'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/group-container'] = array(
-    'title' => 'Group container testing',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_group_container'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/group-fieldset'] = array(
-    'title' => 'Group fieldset testing',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_group_fieldset'),
-    'access callback' => TRUE,
-  );
-  $items['form-test/group-vertical-tabs'] = array(
-    'title' => 'Group vertical tabs testing',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_group_vertical_tabs'),
-    'access callback' => TRUE,
-  );
-
-  $items['form-test/form_state-database'] = array(
-    'title' => t('Form state with a database connection'),
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('form_test_form_state_database'),
-    'access callback' => TRUE,
-  );
-
-  return $items;
-}
-
-
 /**
  * Implements hook_permission().
  */
@@ -364,6 +41,8 @@ function _form_test_submit_values_json($form, &$form_state) {
 
 /**
  * Form builder for testing hook_form_alter() and hook_form_FORM_ID_alter().
+ *
+ * @deprecated Use \Drupal\form_test\alterForm()
  */
 function form_test_alter_form($form, &$form_state) {
   // Elements can be added as needed for future testing needs, but for now,
@@ -413,6 +92,8 @@ function system_form_form_test_alter_form_alter(&$form, &$form_state) {
  *   structure and the alterations should be contained in the rebuilt form.
  * - #validate handlers should be able to alter the $form and the alterations
  *   should be contained in the rebuilt form.
+ *
+ * @deprecated Use \Drupal\form_test\validateForm()
  */
 function form_test_validate_form($form, &$form_state) {
   $object = new Callbacks();
@@ -454,6 +135,8 @@ function form_test_validate_form_validate(&$form, &$form_state) {
 
 /**
  * Form constructor to test the #required property.
+ *
+ * @deprecated Use \Drupal\form_test\validateRequiredForm()
  */
 function form_test_validate_required_form($form, &$form_state) {
   $options = drupal_map_assoc(array('foo', 'bar'));
@@ -522,6 +205,8 @@ function form_test_validate_required_form_submit($form, &$form_state) {
 
 /**
  * Form constructor to test the #required property without #title.
+ *
+ * @deprecated Use \Drupal\form_test\validateRequiredFormNoTitle()
  */
 function form_test_validate_required_form_no_title($form, &$form_state) {
   $form['textfield'] = array(
@@ -542,6 +227,8 @@ function form_test_validate_required_form_no_title_submit($form, &$form_state) {
 
 /**
  * Builds a simple form with a button triggering partial validation.
+ *
+ * @deprecated Use \Drupal\form_test\validateFormWithErrorSuppression()
  */
 function form_test_limit_validation_errors_form($form, &$form_state) {
   $form['title'] = array(
@@ -625,6 +312,8 @@ function form_test_limit_validation_errors_form_partial_submit($form, $form_stat
 
 /**
  * Builds a simple form using the FAPI #pattern proterty.
+ *
+ * @deprecated Use \Drupal\form_test\validatePattern()
  */
 function form_test_pattern_form($form, &$form_state) {
   $form['textfield'] = array(
@@ -730,6 +419,8 @@ function _form_test_tableselect_form_builder($form, $form_state, $element_proper
 
 /**
  * Test the tableselect #multiple = TRUE functionality.
+ *
+ * @deprecated Use \Drupal\form_test\testTableSelectCheckboxes()
  */
 function _form_test_tableselect_multiple_true_form($form, $form_state) {
   return _form_test_tableselect_form_builder($form, $form_state, array('#multiple' => TRUE));
@@ -747,6 +438,8 @@ function _form_test_tableselect_multiple_true_form_submit($form, &$form_state) {
 
 /**
  * Test the tableselect #multiple = FALSE functionality.
+ *
+ * @deprecated Use \Drupal\form_test\testTableSelectRadios()
  */
 function _form_test_tableselect_multiple_false_form($form, $form_state) {
   return _form_test_tableselect_form_builder($form, $form_state, array('#multiple' => FALSE));
@@ -754,6 +447,8 @@ function _form_test_tableselect_multiple_false_form($form, $form_state) {
 
 /**
  * Test the tableselect #colspan functionality.
+ *
+ * @deprecated Use \Drupal\form_test\testTableSelectColspan()
  */
 function _form_test_tableselect_colspan_form($form, $form_state) {
   list($header, $options) = _form_test_tableselect_get_data();
@@ -784,6 +479,8 @@ function _form_test_tableselect_multiple_false_form_submit($form, &$form_state)
 
 /**
  * Test functionality of the tableselect #empty property.
+ *
+ * @deprecated Use \Drupal\form_test\testTableSelectEmptyText()
  */
 function _form_test_tableselect_empty_form($form, $form_state) {
   return _form_test_tableselect_form_builder($form, $form_state, array('#options' => array()));
@@ -791,6 +488,8 @@ function _form_test_tableselect_empty_form($form, $form_state) {
 
 /**
  * Test functionality of the tableselect #js_select property.
+ *
+ * @deprecated Use \Drupal\form_test\testTableSelectJS()
  */
 function _form_test_tableselect_js_select_form($form, $form_state, $action) {
   switch ($action) {
@@ -816,6 +515,8 @@ function _form_test_tableselect_js_select_form($form, $form_state, $action) {
 
 /**
  * Tests functionality of vertical tabs.
+ *
+ * @deprecated Use \Drupal\form_test\testVerticalTabs()
  */
 function _form_test_vertical_tabs_form($form, &$form_state) {
   $form['vertical_tabs'] = array(
@@ -853,6 +554,8 @@ function _form_test_vertical_tabs_form($form, &$form_state) {
  * it would be the case, if the form would contain some #ajax callbacks.
  *
  * @see form_test_storage_form_submit()
+ *
+ * @deprecated Use \Drupal\form_test\testStorage()
  */
 function form_test_storage_form($form, &$form_state) {
   if ($form_state['rebuild']) {
@@ -949,6 +652,8 @@ function form_test_storage_form_submit($form, &$form_state) {
 
 /**
  * A form for testing form labels and required marks.
+ *
+ * @deprecated Use \Drupal\form_test\testLabel()
  */
 function form_label_test_form() {
   $form['form_checkboxes_test'] = array(
@@ -1060,6 +765,8 @@ function form_test_wrapper_callback_wrapper($form, &$form_state) {
 
 /**
  * Form builder for form wrapper callback test.
+ *
+ * @deprecated Use \Drupal\form_test\testWrapperCallback()
  */
 function form_test_wrapper_callback_form($form, &$form_state) {
   $form['builder'] = array('#markup' => 'Form builder element output.');
@@ -1068,6 +775,8 @@ function form_test_wrapper_callback_form($form, &$form_state) {
 
 /**
  * Form builder for form_state_values_clean() test.
+ *
+ * @deprecated Use \Drupal\form_test\testFormStateClean()
  */
 function form_test_form_state_values_clean_form($form, &$form_state) {
   // Build an example form containing multiple submit and button elements; not
@@ -1095,6 +804,8 @@ function form_test_form_state_values_clean_form_submit($form, &$form_state) {
 
 /**
  * Form constructor for the form_state_values_clean() test.
+ *
+ * @deprecated Use \Drupal\form_test\testFormStateCleanAdvanced()
  */
 function form_test_form_state_values_clean_advanced_form($form, &$form_state) {
   // Build an example form containing a managed file and a submit form element.
@@ -1122,6 +833,8 @@ function form_test_form_state_values_clean_advanced_form_submit($form, &$form_st
 
 /**
  * Build a form to test a checkbox.
+ *
+ * @deprecated Use \Drupal\form_test\testCheckbox()
  */
 function _form_test_checkbox($form, &$form_state) {
   $form['#submit'] = array('_form_test_submit_values_json');
@@ -1191,6 +904,8 @@ function _form_test_checkbox($form, &$form_state) {
 
 /**
  * Builds a form to test #type 'select' validation.
+ *
+ * @deprecated Use \Drupal\form_test\testSelect()
  */
 function form_test_select($form, &$form_state) {
   $form['#submit'] = array('_form_test_submit_values_json');
@@ -1294,6 +1009,8 @@ function form_test_select($form, &$form_state) {
 
 /**
  * Builds a form to test select elements when #options is not an array.
+ *
+ * @deprecated Use \Drupal\form_test\testEmptySelect()
  */
 function form_test_empty_select($form, &$form_state) {
   $form['empty_select'] = array(
@@ -1307,6 +1024,8 @@ function form_test_empty_select($form, &$form_state) {
 
 /**
  * Builds a form to test the language select form element.
+ *
+ * @deprecated Use \Drupal\form_test\testLanguageSelect()
  */
 function form_test_language_select() {
   $form['#submit'] = array('_form_test_submit_values_json');
@@ -1351,6 +1070,10 @@ function form_test_language_select() {
  *
  * @param $element
  *   The element type to test. Can be 'number' or 'range'. Defaults to 'number'.
+ *
+ * @deprecated Use \Drupal\form_test\testNumber()
+ *
+ * @deprecated Use \Drupal\form_test\testNumberRange()
  */
 function form_test_number($form, &$form_state, $element = 'number') {
   $base = array(
@@ -1469,6 +1192,8 @@ function form_test_number($form, &$form_state, $element = 'number') {
  *
  * @see form_test_range_submit()
  * @ingroup forms
+ *
+ * @deprecated Use \Drupal\form_test\testRange()
  */
 function form_test_range($form, &$form_state) {
   $form['#submit'] = array('_form_test_submit_values_json');
@@ -1516,6 +1241,8 @@ function form_test_range($form, &$form_state) {
  * Form constructor for testing invalid #type 'range' elements.
  *
  * @ingroup forms
+ *
+ * @deprecated Use \Drupal\form_test\testRangeInvalid()
  */
 function form_test_range_invalid($form, &$form_state) {
   $form['minmax'] = array(
@@ -1537,6 +1264,8 @@ function form_test_range_invalid($form, &$form_state) {
  *
  * @see form_test_color_submit()
  * @ingroup forms
+ *
+ * @deprecated Use \Drupal\form_test\testColor()
  */
 function form_test_color($form, &$form_state) {
   $form['#submit'] = array('_form_test_submit_values_json');
@@ -1554,6 +1283,8 @@ function form_test_color($form, &$form_state) {
 
 /**
  * Builds a form to test the placeholder attribute.
+ *
+ * @deprecated Use \Drupal\form_test\testPlaceholder()
  */
 function form_test_placeholder_test($form, &$form_state) {
   foreach (array('textfield', 'textarea', 'url', 'password', 'search', 'tel', 'email', 'number') as $type) {
@@ -1569,6 +1300,8 @@ function form_test_placeholder_test($form, &$form_state) {
 
 /**
  * Form constructor to test expansion of #type checkboxes and radios.
+ *
+ * @deprecated Use \Drupal\form_test\testCheckboxesRadios()
  */
 function form_test_checkboxes_radios($form, &$form_state, $customize = FALSE) {
   $form['#submit'] = array('_form_test_submit_values_json');
@@ -1631,6 +1364,8 @@ function form_test_checkboxes_radios($form, &$form_state, $customize = FALSE) {
  *
  * @see form_test_email_submit()
  * @ingroup forms
+ *
+ * @deprecated Use \Drupal\form_test\testEmail()
  */
 function form_test_email($form, &$form_state) {
   $form['#submit'] = array('_form_test_submit_values_json');
@@ -1657,6 +1392,8 @@ function form_test_email($form, &$form_state) {
  *
  * @see form_test_url_submit()
  * @ingroup forms
+ *
+ * @deprecated Use \Drupal\form_test\testUrl()
  */
 function form_test_url($form, &$form_state) {
   $form['#submit'] = array('_form_test_submit_values_json');
@@ -1680,6 +1417,8 @@ function form_test_url($form, &$form_state) {
 
 /**
  * Build a form to test disabled elements.
+ *
+ * @deprecated Use \Drupal\form_test\testDisabledElements()
  */
 function _form_test_disabled_elements($form, &$form_state) {
   $form['#submit'] = array('_form_test_submit_values_json');
@@ -1879,6 +1618,8 @@ function _form_test_disabled_elements($form, &$form_state) {
 
 /**
  * Build a form to test input forgery of enabled elements.
+ *
+ * @deprecated Use \Drupal\form_test\testInputForgery()
  */
 function _form_test_input_forgery($form, &$form_state) {
   $form['#submit'] = array('_form_test_submit_values_json');
@@ -1902,6 +1643,8 @@ function _form_test_input_forgery($form, &$form_state) {
 
 /**
  * Form builder for testing preservation of values during a rebuild.
+ *
+ * @deprecated Use \Drupal\form_test\testRebuildPreservation()
  */
 function form_test_form_rebuild_preserve_values_form($form, &$form_state) {
   // Start the form with two checkboxes, to test different defaults, and a
@@ -1980,6 +1723,8 @@ function form_test_form_rebuild_preserve_values_form_submit($form, &$form_state)
 
 /**
  * Form constructor for testing form state persistence.
+ *
+ * @deprecated Use \Drupal\form_test\testStatePersistence()
  */
 function form_test_state_persist($form, &$form_state) {
   $form['title'] = array(
@@ -2101,8 +1846,10 @@ function form_test_programmatic_form_submit($form, &$form_state) {
 
 /**
  * Form builder to test button click detection.
+ *
+ * @deprecated Use \Drupal\form_test\testClickedButton()
  */
-function form_test_clicked_button($form, &$form_state) {
+function form_test_clicked_button($form, &$form_state, $first, $second, $third) {
   // A single text field. In IE, when a form has only one non-button input field
   // and the ENTER key is pressed while that field has focus, the form is
   // submitted without any information identifying the button responsible for
@@ -2119,7 +1866,7 @@ function form_test_clicked_button($form, &$form_state) {
   // 'image_button', and a 'button' with #access=FALSE. This enables form.test
   // to test a variety of combinations.
   $i=0;
-  $args = array_slice(arg(), 2);
+  $args = array($first, $second, $third);
   foreach ($args as $arg) {
     $name = 'button' . ++$i;
     // 's', 'b', or 'i' in the argument define the button type wanted.
@@ -2179,6 +1926,8 @@ function form_test_clicked_button_submit($form, &$form_state) {
 
 /**
  * Form builder to detect form redirect.
+ *
+ * @deprecated Use \Drupal\form_test\testRedirect()
  */
 function form_test_redirect($form, &$form_state) {
   $form['redirection'] = array(
@@ -2240,24 +1989,6 @@ function form_test_user_register_form_rebuild($form, &$form_state) {
   $form_state['rebuild'] = TRUE;
 }
 
-/**
- * Menu callback for testing custom form includes.
- */
-function form_test_load_include_custom($form, &$form_state) {
-  $form['button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-    '#submit' => array('form_test_load_include_submit'),
-  );
-  // Specify the include file and enable form caching. That way the form is
-  // cached when it is submitted, but needs to find the specified submit handler
-  // in the include.
-  // Filename is a bit weird here: modules/system/tests/form_test.file.inc
-  form_load_include($form_state, 'inc', 'form_test', 'form_test.file');
-  $form_state['cache'] = TRUE;
-  return $form;
-}
-
 function form_test_checkbox_type_juggling($form, $form_state, $default_value, $return_value) {
   $form['checkbox'] = array(
     '#title' => t('Checkbox'),
@@ -2268,6 +1999,11 @@ function form_test_checkbox_type_juggling($form, $form_state, $default_value, $r
   return $form;
 }
 
+/**
+ * Tests checkboxes zero.
+ *
+ * @deprecated Use \Drupal\form_test\testCheckboxesZero()
+ */
 function form_test_checkboxes_zero($form, &$form_state, $json = TRUE) {
   $form['checkbox_off'] = array(
     '#title' => t('Checkbox off'),
@@ -2305,6 +2041,8 @@ function _form_test_checkboxes_zero_no_redirect($form, &$form_state) {
 
 /**
  * Builds a form to test the required attribute.
+ *
+ * @deprecated Use \Drupal\form_test\testRequired()
  */
 function form_test_required_attribute($form, &$form_state) {
   foreach (array('textfield', 'textarea', 'password') as $type) {
@@ -2348,6 +2086,8 @@ function form_test_html_id($form, &$form_state) {
 
 /**
  * Builds a simple form to test form button classes.
+ *
+ * @deprecated Use \Drupal\form_test\testButtonClass()
  */
 function form_test_button_class($form, &$form_state) {
   $form['button'] = array(
@@ -2365,6 +2105,8 @@ function form_test_button_class($form, &$form_state) {
 
 /**
  * Builds a simple form to test the #group property on #type 'details'.
+ *
+ * @deprecated Use \Drupal\form_test\testGroupDetails()
  */
 function form_test_group_details() {
   $form['details'] = array(
@@ -2385,6 +2127,8 @@ function form_test_group_details() {
 
 /**
  * Builds a simple form to test the #group property on #type 'container'.
+ *
+ * @deprecated Use \Drupal\form_test\testGroupContainer()
  */
 function form_test_group_container() {
   $form['container'] = array(
@@ -2404,6 +2148,8 @@ function form_test_group_container() {
 
 /**
  * Builds a simple form to test the #group property on #type 'fieldset'.
+ *
+ * @deprecated Use \Drupal\form_test\testGroupFieldset()
  */
 function form_test_group_fieldset() {
   $form['fieldset'] = array(
@@ -2424,6 +2170,8 @@ function form_test_group_fieldset() {
 
 /**
  * Builds a simple form to test the #group property on #type 'vertical_tabs'.
+ *
+ * @deprecated Use \Drupal\form_test\testGroupVerticalTabs()
  */
 function form_test_group_vertical_tabs() {
   $form['vertical_tabs'] = array(
@@ -2452,6 +2200,8 @@ function form_test_group_vertical_tabs() {
 
 /**
  * Builds a form which gets the database connection stored in the form state.
+ *
+ * @deprecated Use \Drupal\form_test\testFormStateDatabase()
  */
 function form_test_form_state_database($form, &$form_state) {
   $form['text'] = array(
diff --git a/core/modules/system/tests/modules/form_test/form_test.routing.yml b/core/modules/system/tests/modules/form_test/form_test.routing.yml
index e0997a5d4f6ef9b252c7ef1b71c9873d03c4ed5d..f8467ff6878fac9b11fa7fe89efb4bc4721f033c 100644
--- a/core/modules/system/tests/modules/form_test/form_test.routing.yml
+++ b/core/modules/system/tests/modules/form_test/form_test.routing.yml
@@ -84,3 +84,352 @@ form_test.double_form:
     _content: '\Drupal\form_test\Controller\FormTestController::doubleForm'
   requirements:
     _access: 'TRUE'
+
+form_test.alter_form:
+  path: '/form-test/alter'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::alterForm'
+    _title: 'Form altering test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.validate_form:
+  path: '/form-test/validate'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::validateForm'
+    _title: 'Form validation handlers test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.validate_required:
+  path: '/form-test/validate-required'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::validateRequiredForm'
+    _title: 'Form #required validation'
+  requirements:
+    _access: 'TRUE'
+
+form_test.validate_required_no_title:
+  path: '/form-test/validate-required-no-title'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::validateRequiredFormNoTitle'
+    _title: 'Form #required validation without #title'
+  requirements:
+    _access: 'TRUE'
+
+form_test.validate_with_error_suppresion:
+  path: '/form-test/limit-validation-errors'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::validateFormWithErrorSuppression'
+    _title: 'Form validation with some error suppression'
+  requirements:
+    _access: 'TRUE'
+
+form_test.pattern:
+  path: '/form-test/pattern'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::validatePattern'
+    _title: 'Pattern validation'
+  requirements:
+    _access: 'TRUE'
+
+form_test.tableselect_checkboxes:
+  path: '/form_test/tableselect/multiple-true'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testTableSelectCheckboxes'
+    _title: 'Tableselect checkboxes test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.tableselect_radios:
+  path: '/form_test/tableselect/multiple-false'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testTableSelectRadios'
+    _title: 'Tableselect radio button test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.tableselect_colspan:
+  path: '/form_test/tableselect/colspan'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testTableSelectColspan'
+    _title: 'Tableselect colspan test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.tableselect_empty_text:
+  path: '/form_test/tableselect/empty-text'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testTableSelectEmptyText'
+    _title: 'Tableselect empty text test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.tableselect_js:
+  path: '/form_test/tableselect/advanced-select/{test_action}'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testTableSelectJS'
+    _title: 'Tableselect js_select tests'
+  requirements:
+    _access: 'TRUE'
+
+form_test.vertical_tabs:
+  path: '/form_test/vertical-tabs'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testVerticalTabs'
+    _title: 'Vertical tabs tests'
+  requirements:
+    _access: 'TRUE'
+
+form_test.storage:
+  path: '/form_test/form-storage'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testStorage'
+    _title: 'Form storage test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.state_clean:
+  path: '/form_test/form-state-values-clean'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testFormStateClean'
+    _title: 'Form state values clearance test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.state_clean_advanced:
+  path: '/form_test/form-state-values-clean-advanced'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testFormStateCleanAdvanced'
+    _title: 'Form state values clearance advanced test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.checkbox:
+  path: '/form-test/checkbox'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testCheckbox'
+    _title: 'Form test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.select:
+  path: '/form-test/select'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testSelect'
+    _title: 'Select'
+  requirements:
+    _access: 'TRUE'
+
+form_test.empty_select:
+  path: '/form-test/empty-select'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testEmptySelect'
+    _title: 'Empty Select Element'
+  requirements:
+    _access: 'TRUE'
+
+form_test.language_select:
+  path: '/form-test/language_select'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testLanguageSelect'
+    _title: 'Language Select'
+  requirements:
+    _access: 'TRUE'
+
+form_test.placeholder:
+  path: '/form-test/placeholder-text'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testPlaceholder'
+    _title: 'Placeholder'
+  requirements:
+    _access: 'TRUE'
+
+form_test.number:
+  path: '/form-test/number'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testNumber'
+    _title: 'Number'
+  requirements:
+    _access: 'TRUE'
+
+form_test.number_range:
+  path: '/form-test/number/range'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testNumberRange'
+    _title: 'Range'
+  requirements:
+    _access: 'TRUE'
+
+form_test.range:
+  path: '/form-test/range'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testRange'
+    _title: 'Range'
+  requirements:
+    _access: 'TRUE'
+
+form_test.range_invalid:
+  path: '/form-test/range/invalid'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testRangeInvalid'
+    _title: 'Invalid range'
+  requirements:
+    _access: 'TRUE'
+
+form_test.color:
+  path: '/form-test/color'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testColor'
+    _title: 'Color'
+  requirements:
+    _access: 'TRUE'
+
+form_test.checkboxes_radios:
+  path: '/form-test/checkboxes-radios/{customize}'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testCheckboxesRadios'
+    _title: 'Checkboxes, Radios'
+    customize: FALSE
+  requirements:
+    _access: 'TRUE'
+
+form_test.email:
+  path: '/form-test/email'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testEmail'
+    _title: 'E-Mail fields'
+  requirements:
+    _access: 'TRUE'
+
+form_test.url:
+  path: '/form-test/url'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testUrl'
+    _title: 'URL'
+  requirements:
+    _access: 'TRUE'
+
+form_test.disabled_elements:
+  path: '/form-test/disabled-elements'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testDisabledElements'
+    _title: 'Form test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.input_forgery:
+  path: '/form-test/input-forgery'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testInputForgery'
+    _title: 'Form test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.rebuild_preservation:
+  path: '/form-test/form-rebuild-preserve-values'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testRebuildPreservation'
+    _title: 'Form values preservation during rebuild test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.redirect:
+  path: '/form-test/redirect'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testRedirect'
+    _title: 'Redirect test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.label:
+  path: '/form_test/form-labels'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testLabel'
+    _title: 'Form label test'
+  requirements:
+    _access: 'TRUE'
+
+form_test.state_persistence:
+  path: '/form-test/state-persist'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testStatePersistence'
+    _title: 'Form state persistence without storage'
+  requirements:
+    _access: 'TRUE'
+
+form_test.clicked_button:
+  path: '/form-test/clicked-button/{first}/{second}/{third}'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testClickedButton'
+    _title: 'Clicked button test'
+    first: NULL
+    second: NULL
+    third: NULL
+  requirements:
+    _access: 'TRUE'
+
+form_test.checkboxes_zero:
+  path: '/form-test/checkboxes-zero/{json}'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testCheckboxesZero'
+    _title: 'FAPI test involving checkboxes and zero'
+    json: TRUE
+  requirements:
+    _access: 'TRUE'
+
+form_test.required:
+  path: '/form-test/required-attribute'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testRequired'
+    _title: 'Required'
+  requirements:
+    _access: 'TRUE'
+
+form_test.button_class:
+  path: '/form-test/button-class'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testButtonClass'
+    _title: 'Button class testing'
+  requirements:
+    _access: 'TRUE'
+
+form_test.group_details:
+  path: '/form-test/group-details'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testGroupDetails'
+    _title: 'Group details testing'
+  requirements:
+    _access: 'TRUE'
+
+form_test.group_container:
+  path: '/form-test/group-container'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testGroupContainer'
+    _title: 'Group container testing'
+  requirements:
+    _access: 'TRUE'
+
+form_test.group_fieldset:
+  path: '/form-test/group-fieldset'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testGroupFieldset'
+    _title: 'Group fieldset testing'
+  requirements:
+    _access: 'TRUE'
+
+form_test.group_vertical_tabs:
+  path: '/form-test/group-vertical-tabs'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testGroupVerticalTabs'
+    _title: 'Group vertical tabs testing'
+  requirements:
+    _access: 'TRUE'
+
+form_test.form_state_database:
+  path: '/form-test/form_state-database'
+  defaults:
+    _content: '\Drupal\form_test\Form\FormTestForm::testFormStateDatabase'
+    _title: 'Form state with a database connection'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/Form/FormTestForm.php b/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/Form/FormTestForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..6fa4ab00faeee3eb20e9185dca21d77567360d85
--- /dev/null
+++ b/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/Form/FormTestForm.php
@@ -0,0 +1,411 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\form_test\Form\FormTestForm.
+ */
+
+namespace Drupal\form_test\Form;
+
+/**
+ * Temporary form controller for form_test module.
+ */
+class FormTestForm {
+
+  /**
+   * Wraps form_test_alter_form().
+   *
+   * @todo Remove form_test_alter_form().
+   */
+  public function alterForm() {
+    return drupal_get_form('form_test_alter_form');
+  }
+
+  /**
+   * Wraps form_test_validate_form().
+   *
+   * @todo Remove form_test_validate_form().
+   */
+  public function validateForm() {
+    return drupal_get_form('form_test_validate_form');
+  }
+
+  /**
+   * Wraps form_test_validate_required_form().
+   *
+   * @todo Remove form_test_validate_required_form().
+   */
+  public function validateRequiredForm() {
+    return drupal_get_form('form_test_validate_required_form');
+  }
+
+  /**
+   * Wraps form_test_validate_required_form_no_title().
+   *
+   * @todo Remove form_test_validate_required_form_no_title().
+   */
+  public function validateRequiredFormNoTitle() {
+    return drupal_get_form('form_test_validate_required_form_no_title');
+  }
+
+  /**
+   * Wraps form_test_limit_validation_errors_form().
+   *
+   * @todo Remove form_test_limit_validation_errors_form().
+   */
+  public function validateFormWithErrorSuppression() {
+    return drupal_get_form('form_test_limit_validation_errors_form');
+  }
+
+  /**
+   * Wraps form_test_pattern_form().
+   *
+   * @todo Remove form_test_pattern_form().
+   */
+  public function validatePattern() {
+    return drupal_get_form('form_test_pattern_form');
+  }
+
+  /**
+   * Wraps _form_test_tableselect_multiple_true_form().
+   *
+   * @todo Remove _form_test_tableselect_multiple_true_form().
+   */
+  public function testTableSelectCheckboxes() {
+    return drupal_get_form('_form_test_tableselect_multiple_true_form');
+  }
+
+  /**
+   * Wraps _form_test_tableselect_multiple_false_form().
+   *
+   * @todo Remove _form_test_tableselect_multiple_false_form().
+   */
+  public function testTableSelectRadios() {
+    return drupal_get_form('_form_test_tableselect_multiple_false_form');
+  }
+
+  /**
+   * Wraps _form_test_tableselect_colspan_form().
+   *
+   * @todo Remove _form_test_tableselect_colspan_form().
+   */
+  public function testTableSelectColspan() {
+    return drupal_get_form('_form_test_tableselect_colspan_form');
+  }
+
+  /**
+   * Wraps _form_test_tableselect_empty_form().
+   *
+   * @todo Remove _form_test_tableselect_empty_form().
+   */
+  public function testTableSelectEmptyText() {
+    return drupal_get_form('_form_test_tableselect_empty_form');
+  }
+
+  /**
+   * Wraps _form_test_tableselect_js_select_form().
+   *
+   * @todo Remove _form_test_tableselect_js_select_form().
+   */
+  public function testTableSelectJS($test_action) {
+    return drupal_get_form('_form_test_tableselect_js_select_form', $test_action);
+  }
+
+  /**
+   * Wraps _form_test_vertical_tabs_form().
+   *
+   * @todo Remove _form_test_vertical_tabs_form().
+   */
+  public function testVerticalTabs() {
+    return drupal_get_form('_form_test_vertical_tabs_form');
+  }
+
+  /**
+   * Wraps form_test_storage_form().
+   *
+   * @todo Remove form_test_storage_form().
+   */
+  public function testStorage() {
+    return drupal_get_form('form_test_storage_form');
+  }
+
+  /**
+   * Wraps form_test_wrapper_callback_form().
+   *
+   * @todo Remove form_test_wrapper_callback_form().
+   */
+  public function testWrapperCallback() {
+    return drupal_get_form('form_test_wrapper_callback_form');
+  }
+
+  /**
+   * Wraps form_test_form_state_values_clean_form().
+   *
+   * @todo Remove form_test_form_state_values_clean_form().
+   */
+  public function testFormStateClean() {
+    return drupal_get_form('form_test_form_state_values_clean_form');
+  }
+
+  /**
+   * Wraps form_test_form_state_values_clean_advanced_form().
+   *
+   * @todo Remove form_test_form_state_values_clean_advanced_form().
+   */
+  public function testFormStateCleanAdvanced() {
+    return drupal_get_form('form_test_form_state_values_clean_advanced_form');
+  }
+
+  /**
+   * Wraps _form_test_checkbox().
+   *
+   * @todo Remove _form_test_checkbox().
+   */
+  public function testCheckbox() {
+    return drupal_get_form('_form_test_checkbox');
+  }
+
+  /**
+   * Wraps form_test_select().
+   *
+   * @todo Remove form_test_select().
+   */
+  public function testSelect() {
+    return drupal_get_form('form_test_select');
+  }
+
+  /**
+   * Wraps form_test_empty_select().
+   *
+   * @todo Remove form_test_empty_select().
+   */
+  public function testEmptySelect() {
+    return drupal_get_form('form_test_empty_select');
+  }
+
+  /**
+   * Wraps form_test_language_select().
+   *
+   * @todo Remove form_test_language_select().
+   */
+  public function testLanguageSelect() {
+    return drupal_get_form('form_test_language_select');
+  }
+
+  /**
+   * Wraps form_test_placeholder_test().
+   *
+   * @todo Remove form_test_placeholder_test().
+   */
+  public function testPlaceholder() {
+    return drupal_get_form('form_test_placeholder_test');
+  }
+
+  /**
+   * Wraps form_test_number().
+   *
+   * @todo Remove form_test_number().
+   */
+  public function testNumber() {
+    return drupal_get_form('form_test_number');
+  }
+
+  /**
+   * Wraps form_test_number().
+   *
+   * @todo Remove form_test_number().
+   */
+  public function testNumberRange() {
+    return drupal_get_form('form_test_number', 'range');
+  }
+
+  /**
+   * Wraps form_test_range().
+   *
+   * @todo Remove form_test_range().
+   */
+  public function testRange() {
+    return drupal_get_form('form_test_range');
+  }
+
+  /**
+   * Wraps form_test_range_invalid().
+   *
+   * @todo Remove form_test_range_invalid().
+   */
+  public function testRangeInvalid() {
+    return drupal_get_form('form_test_range_invalid');
+  }
+
+  /**
+   * Wraps form_test_color().
+   *
+   * @todo Remove form_test_color().
+   */
+  public function testColor() {
+    return drupal_get_form('form_test_color');
+  }
+
+  /**
+   * Wraps form_test_checkboxes_radios().
+   *
+   * @todo Remove form_test_checkboxes_radios().
+   */
+  public function testCheckboxesRadios($customize) {
+    return drupal_get_form('form_test_checkboxes_radios', $customize);
+  }
+
+  /**
+   * Wraps form_test_email().
+   *
+   * @todo Remove form_test_email().
+   */
+  public function testEmail() {
+    return drupal_get_form('form_test_email');
+  }
+
+  /**
+   * Wraps form_test_url().
+   *
+   * @todo Remove form_test_url().
+   */
+  public function testUrl() {
+    return drupal_get_form('form_test_url');
+  }
+
+  /**
+   * Wraps _form_test_disabled_elements().
+   *
+   * @todo Remove _form_test_disabled_elements().
+   */
+  public function testDisabledElements() {
+    return drupal_get_form('_form_test_disabled_elements');
+  }
+
+  /**
+   * Wraps _form_test_input_forgery().
+   *
+   * @todo Remove _form_test_input_forgery().
+   */
+  public function testInputForgery() {
+    return drupal_get_form('_form_test_input_forgery');
+  }
+
+  /**
+   * Wraps form_test_form_rebuild_preserve_values_form().
+   *
+   * @todo Remove form_test_form_rebuild_preserve_values_form().
+   */
+  public function testRebuildPreservation() {
+    return drupal_get_form('form_test_form_rebuild_preserve_values_form');
+  }
+
+  /**
+   * Wraps form_test_redirect().
+   *
+   * @todo Remove form_test_redirect().
+   */
+  public function testRedirect() {
+    return drupal_get_form('form_test_redirect');
+  }
+
+  /**
+   * Wraps form_label_test_form().
+   *
+   * @todo Remove form_label_test_form().
+   */
+  public function testLabel() {
+    return drupal_get_form('form_label_test_form');
+  }
+
+  /**
+   * Wraps form_test_state_persist().
+   *
+   * @todo Remove form_test_state_persist().
+   */
+  public function testStatePersistence() {
+    return drupal_get_form('form_test_state_persist');
+  }
+
+  /**
+   * Wraps form_test_clicked_button().
+   *
+   * @todo Remove form_test_clicked_button().
+   */
+  public function testClickedButton($first, $second, $third) {
+    return drupal_get_form('form_test_clicked_button', $first, $second, $third);
+  }
+
+  /**
+   * Wraps form_test_checkboxes_zero().
+   *
+   * @todo Remove form_test_checkboxes_zero().
+   */
+  public function testCheckboxesZero($json) {
+    return drupal_get_form('form_test_checkboxes_zero', $json);
+  }
+
+  /**
+   * Wraps form_test_required_attribute().
+   *
+   * @todo Remove form_test_required_attribute().
+   */
+  public function testRequired() {
+    return drupal_get_form('form_test_required_attribute');
+  }
+
+  /**
+   * Wraps form_test_button_class().
+   *
+   * @todo Remove form_test_button_class().
+   */
+  public function testButtonClass() {
+    return drupal_get_form('form_test_button_class');
+  }
+
+  /**
+   * Wraps form_test_group_details().
+   *
+   * @todo Remove form_test_group_details().
+   */
+  public function testGroupDetails() {
+    return drupal_get_form('form_test_group_details');
+  }
+
+  /**
+   * Wraps form_test_group_container().
+   *
+   * @todo Remove form_test_group_container().
+   */
+  public function testGroupContainer() {
+    return drupal_get_form('form_test_group_container');
+  }
+
+  /**
+   * Wraps form_test_group_fieldset().
+   *
+   * @todo Remove form_test_group_fieldset().
+   */
+  public function testGroupFieldset() {
+    return drupal_get_form('form_test_group_fieldset');
+  }
+
+  /**
+   * Wraps form_test_group_vertical_tabs().
+   *
+   * @todo Remove form_test_group_vertical_tabs().
+   */
+  public function testGroupVerticalTabs() {
+    return drupal_get_form('form_test_group_vertical_tabs');
+  }
+
+  /**
+   * Wraps form_test_form_state_database().
+   *
+   * @todo Remove form_test_form_state_database().
+   */
+  public function testFormStateDatabase() {
+    return drupal_get_form('form_test_form_state_database');
+  }
+
+}