diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestResultsForm.php b/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestResultsForm.php
index 844e9ef..b788c56 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestResultsForm.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestResultsForm.php
@@ -111,7 +111,6 @@ public function buildForm(array $form, array &$form_state, $test_id = NULL) {
       '#title' => t('Results'),
     );
     $form['result']['summary'] = $summary = array(
-      '#theme' => 'simpletest_result_summary',
       '#pass' => 0,
       '#fail' => 0,
       '#exception' => 0,
@@ -162,7 +161,7 @@ public function buildForm(array $form, array &$form_state, $test_id = NULL) {
         $form['result']['summary']['#' . $assertion->status]++;
       }
       $form['result']['results'][$group]['table'] = array(
-        '#theme' => 'table',
+        '#type' => 'table',
         '#header' => $header,
         '#rows' => $rows,
       );
@@ -173,11 +172,25 @@ public function buildForm(array $form, array &$form_state, $test_id = NULL) {
 
       // Store test group (class) as for use in filter.
       $filter[$group_summary['#ok'] ? 'pass' : 'fail'][] = $group;
+
+      // Render summary information.
+      $group_summary += array(
+        '#prefix' => '<div class="simpletest-' . ($group_summary['#ok'] ? 'pass' : 'fail') . '">',
+        '#markup' => _simpletest_format_summary_line($group_summary),
+        '#suffix' => '</div>',
+      );
     }
 
     // Overal summary status.
     $form['result']['summary']['#ok'] = $form['result']['summary']['#fail'] + $form['result']['summary']['#exception'] == 0;
 
+    // Render overall summary.
+    $form['result']['summary'] += array(
+      '#prefix' => '<div class="simpletest-' . ($form['result']['summary']['#ok'] ? 'pass' : 'fail') . '">',
+      '#markup' => _simpletest_format_summary_line($form['result']['summary']),
+      '#suffix' => '</div>',
+    );
+
     // Actions.
     $form['#action'] = url('admin/config/development/testing/results/re-run');
     $form['action'] = array(
diff --git a/core/modules/simpletest/simpletest.css b/core/modules/simpletest/simpletest.css
index 86bd04b..0337e62 100644
--- a/core/modules/simpletest/simpletest.css
+++ b/core/modules/simpletest/simpletest.css
@@ -30,8 +30,12 @@ th.simpletest_test {
   background-color: #edf5fa;
   color: #494949;
 }
+.simpletest-test-select .form-item {
+  margin-bottom: 0;
+  margin-top: 0;
+}
 
-table#simpletest-form-table tr.simpletest-group label {
+#simpletest-form-table tr.simpletest-group label {
   display: inline;
 }
 
diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index 06e56e7..6b47d85 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -77,10 +77,7 @@ function simpletest_theme() {
     'simpletest_test_table' => array(
       'render element' => 'table',
       'file' => 'simpletest.theme.inc',
-    ),
-    'simpletest_result_summary' => array(
-      'render element' => 'form',
-      'file' => 'simpletest.theme.inc',
+      'template' => 'simpletest-test-table',
     ),
   );
 }
diff --git a/core/modules/simpletest/simpletest.theme.inc b/core/modules/simpletest/simpletest.theme.inc
index f7b5e6f..87acab5 100644
--- a/core/modules/simpletest/simpletest.theme.inc
+++ b/core/modules/simpletest/simpletest.theme.inc
@@ -5,27 +5,74 @@
  * Page callbacks for simpletest module.
  */
 
+use Drupal\Core\Template\Attribute;
+
 /**
- * Returns HTML for a test list generated by simpletest_test_form() into a table.
+ * List tests arranged in groups that can be selected and run.
+ */
+function simpletest_test_form($form, &$form_state) {
+  $form['tests'] = array(
+    '#type' => 'details',
+    '#title' => t('Tests'),
+    '#description' => t('Select the test(s) or test group(s) you would like to run, and click <em>Run tests</em>.'),
+  );
+
+  $form['tests']['table'] = array(
+    '#theme' => 'simpletest_test_table',
+  );
+
+  // Generate the list of tests arranged by group.
+  $groups = simpletest_test_get_all();
+  $groups['PHPUnit'] = simpletest_phpunit_get_available_tests();
+  $form_state['storage']['PHPUnit'] = $groups['PHPUnit'];
+
+  foreach ($groups as $group => $tests) {
+    $form['tests']['table'][$group] = array(
+      '#collapsed' => TRUE,
+    );
+
+    foreach ($tests as $class => $info) {
+      $form['tests']['table'][$group][$class] = array(
+        '#type' => 'checkbox',
+        '#title' => $info['name'],
+        '#description' => $info['description'],
+      );
+    }
+  }
+
+  // Operation buttons.
+  $form['tests']['op'] = array(
+    '#type' => 'submit',
+    '#value' => t('Run tests'),
+  );
+  $form['clean'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Clean test environment'),
+    '#description' => t('Remove tables with the prefix "simpletest" and temporary directories that are left over from tests that crashed. This is intended for developers when creating tests.'),
+  );
+  $form['clean']['op'] = array(
+    '#type' => 'submit',
+    '#value' => t('Clean environment'),
+    '#submit' => array('simpletest_clean_environment'),
+  );
+
+  return $form;
+}
+
+/**
+ * Prepares variables for test list table templates.
+ *
+ * Default template: simpletest-test-table.html.twig.
  *
- * @param $variables
+ * @param array $variables
  *   An associative array containing:
  *   - table: A render element representing the table.
- *
- * @ingroup themeable
  */
-function theme_simpletest_test_table($variables) {
+function template_preprocess_simpletest_test_table(&$variables) {
   $table = $variables['table'];
 
   drupal_add_library('simpletest', 'drupal.simpletest');
 
-  // Create header for test selection table.
-  $header = array(
-    array('class' => array('select-all')),
-    array('data' => t('Test'), 'class' => array('simpletest_test')),
-    array('data' => t('Description'), 'class' => array('simpletest_description')),
-  );
-
   // Define the images used to expand/collapse the test groups.
   $js = array(
     'images' => array(
@@ -35,36 +82,25 @@ function theme_simpletest_test_table($variables) {
   );
 
   // Cycle through each test group and create a row.
-  $rows = array();
+
+  $variables['test_groups'] = array();
   foreach (element_children($table) as $key) {
     $element = &$table[$key];
-    $row = array();
+
+    $variables['test_groups'][$key] = new stdClass();
 
     // Make the class name safe for output on the page by replacing all
     // non-word/decimal characters with a dash (-).
     $test_class = strtolower(trim(preg_replace("/[^\w\d]/", "-", $key)));
+    $variables['test_groups'][$key]->test_class = $test_class;
 
     // Select the right "expand"/"collapse" image, depending on whether the
     // category is expanded (at least one test selected) or not.
     $collapsed = !empty($element['#collapsed']);
     $image_index = $collapsed ? 0 : 1;
 
-    // Place-holder for checkboxes to select group of tests.
-    $row[] = array('id' => $test_class, 'class' => array('simpletest-select-all'));
-
     // Expand/collapse image and group title.
-    $row[] = array(
-      'data' => '<div class="simpletest-image" id="simpletest-test-group-' . $test_class . '"></div>' .
-        '<label for="' . $test_class . '-select-all" class="simpletest-group-label">' . $key . '</label>',
-      'class' => array('simpletest-group-label'),
-    );
-
-    $row[] = array(
-      'data' => '&nbsp;',
-      'class' => array('simpletest-group-description'),
-    );
-
-    $rows[] = array('data' => $row, 'class' => array('simpletest-group'));
+    $variables['test_groups'][$key]->label = $key;
 
     // Add individual tests to group.
     $current_js = array(
@@ -77,63 +113,65 @@ function theme_simpletest_test_table($variables) {
     // Sorting $element by children's #title attribute instead of by class name.
     uasort($element, 'element_sort_by_title');
 
+    $variables['test_groups'][$key]->tests = array();
+
     // Cycle through each test within the current group.
     foreach (element_children($element) as $test_name) {
       $test = $element[$test_name];
-      $row = array();
+      $test_data = new stdClass();
+      $test_data->attributes = new Attribute(array('class' => array()));
+      $test_data->id = $test['#id'];
 
       $current_js['testNames'][] = $test['#id'];
 
       // Store test title and description so that checkbox won't render them.
-      $title = $test['#title'];
-      $description = $test['#description'];
+      $test_data->title = $test['#title'];
+      $test_data->description = $test['#description'];
+      unset($test['#description']);
 
       $test['#title_display'] = 'invisible';
-      unset($test['#description']);
 
       // Test name is used to determine what tests to run.
       $test['#name'] = $test_name;
 
-      $row[] = array(
-        'data' => drupal_render($test),
-        'class' => array('simpletest-test-select'),
-      );
-      $row[] = array(
-        'data' => '<label for="' . $test['#id'] . '">' . $title . '</label>',
-        'class' => array('simpletest-test-label'),
-      );
-      $row[] = array(
-        'data' => '<div class="description">' . $description . '</div>',
-        'class' => array('simpletest-test-description'),
-      );
+      // Add the checkbox field.
+      $test_data->field = $test;
+
+      $test_data->attributes['class'][] = $test_class . '-test';
+      $test_data->attributes['class'][] = ($collapsed ? 'js-hide' : '');
 
-      $rows[] = array('data' => $row, 'class' => array($test_class . '-test', ($collapsed ? 'js-hide' : '')));
+      $variables['test_groups'][$key]->tests[$test_name] = $test_data;
     }
     $js['simpletest-test-group-' . $test_class] = $current_js;
-    unset($table[$key]);
   }
 
   // Add js array of settings.
   drupal_add_js(array('simpleTest' => $js), 'setting');
-
-  if (empty($rows)) {
-    return '<strong>' . t('No tests to display.') . '</strong>';
-  }
-  else {
-    return theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'simpletest-form-table')));
-  }
 }
 
 /**
- * Returns HTML for the summary status of a simpletest result.
- *
- * @param $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @ingroup themeable
+ * Run selected tests.
  */
-function theme_simpletest_result_summary($variables) {
-  $form = $variables['form'];
-  return '<div class="simpletest-' . ($form['#ok'] ? 'pass' : 'fail') . '">' . _simpletest_format_summary_line($form) . '</div>';
+function simpletest_test_form_submit($form, &$form_state) {
+  // Get list of tests.
+  $tests_list = array();
+  simpletest_classloader_register();
+
+  $phpunit_all = array_keys($form_state['storage']['PHPUnit']);
+
+  foreach ($form_state['values'] as $class_name => $value) {
+    // Since class_exists() will likely trigger an autoload lookup,
+    // we do the fast check first.
+    if ($value === 1 && class_exists($class_name)) {
+      $test_type = in_array($class_name, $phpunit_all) ? 'UnitTest' : 'WebTest';
+      $tests_list[$test_type][] = $class_name;
+    }
+  }
+  if (count($tests_list) > 0 ) {
+    $test_id = simpletest_run_tests($tests_list, 'drupal');
+    $form_state['redirect'] = 'admin/config/development/testing/results/' . $test_id;
+  }
+  else {
+    drupal_set_message(t('No test(s) selected.'), 'error');
+  }
 }
