';
- $context['message'] .= theme('item_list', array('items' => $items));
-
- // Save working values for the next iteration.
- $context['sandbox']['tests'] = $test_list;
- $context['sandbox']['test_results'] = $test_results;
- // The test_id is the only thing we need to save for the report page.
- $context['results']['test_id'] = $test_id;
-
- // Multistep processing: report progress.
- $context['finished'] = 1 - $size / $max;
-}
-
-function _simpletest_batch_finished($success, $results, $operations, $elapsed) {
- if ($success) {
- drupal_set_message(t('The test run finished in @elapsed.', array('@elapsed' => $elapsed)));
- }
- else {
- // Use the test_id passed as a parameter to _simpletest_batch_operation().
- $test_id = $operations[0][1][1];
-
- // Retrieve the last database prefix used for testing and the last test
- // class that was run from. Use the information to read the lgo file
- // in case any fatal errors caused the test to crash.
- list($last_prefix, $last_test_class) = simpletest_last_test_get($test_id);
- simpletest_log_read($test_id, $last_prefix, $last_test_class);
-
-
- drupal_set_message(t('The test run did not successfully finish.'), 'error');
- drupal_set_message(t('Use the Clean environment button to clean-up temporary files and tables.'), 'warning');
- }
- module_invoke_all('test_group_finished');
-}
-
/*
* Get information about the last test that ran given a test ID.
*
@@ -299,79 +238,6 @@
}
/**
- * Get a list of all of the tests provided by the system.
- *
- * The list of test classes is loaded from the registry where it looks for
- * files ending in ".test". Once loaded the test list is cached and stored in
- * a static variable. In order to list tests provided by disabled modules
- * hook_registry_files_alter() is used to forcefully add them to the registry.
- *
- * @return
- * An array of tests keyed with the groups specified in each of the tests
- * getInfo() method and then keyed by the test class. An example of the array
- * structure is provided below.
- *
- * @code
- * $groups['Blog'] => array(
- * 'BlogTestCase' => array(
- * 'name' => 'Blog functionality',
- * 'description' => 'Create, view, edit, delete, ...',
- * 'group' => 'Blog',
- * ),
- * );
- * @endcode
- * @see simpletest_registry_files_alter()
- */
-function simpletest_test_get_all() {
- $groups = &drupal_static(__FUNCTION__);
-
- if (!$groups) {
- // Load test information from cache if available, otherwise retrieve the
- // information from each tests getInfo() method.
- if ($cache = cache_get('simpletest', 'cache')) {
- $groups = $cache->data;
- }
- else {
- // Select all clases in files ending with .test.
- $classes = db_query("SELECT name FROM {registry} WHERE type = :type AND filename LIKE :name", array(':type' => 'class', ':name' => '%.test'));
-
- // Check that each class has a getInfo() method and store the information
- // in an array keyed with the group specified in the test information.
- $groups = array();
- foreach ($classes as $class) {
- $class = $class->name;
- // Test classes need to implement getInfo() to be valid.
- if (class_exists($class) && method_exists($class, 'getInfo')) {
- $info = call_user_func(array($class, 'getInfo'));
-
- // If this test class requires a non-existing module, skip it.
- if (!empty($info['dependencies'])) {
- foreach ($info['dependencies'] as $module) {
- if (!drupal_get_filename('module', $module)) {
- continue 2;
- }
- }
- }
-
- $groups[$info['group']][$class] = $info;
- }
- }
-
- // Sort the groups and tests within the groups by name.
- uksort($groups, 'strnatcasecmp');
- foreach ($groups as $group => &$tests) {
- uksort($tests, 'strnatcasecmp');
- }
-
- // Allow modules extending core tests to disable originals.
- drupal_alter('simpletest', $groups);
- cache_set('simpletest', $groups);
- }
- }
- return $groups;
-}
-
-/**
* Implements hook_registry_files_alter().
*
* Add the test files for disabled modules so that we get a list containing
Index: modules/simpletest/simpletest.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.pages.inc,v
retrieving revision 1.28
diff -u -r1.28 simpletest.pages.inc
--- modules/simpletest/simpletest.pages.inc 13 Apr 2010 15:23:03 -0000 1.28
+++ modules/simpletest/simpletest.pages.inc 21 Apr 2010 04:25:15 -0000
@@ -7,426 +7,6 @@
*/
/**
- * List tests arranged in groups that can be selected and run.
- */
-function simpletest_test_form($form) {
- $form['tests'] = array(
- '#type' => 'fieldset',
- '#title' => t('Tests'),
- '#description' => t('Select the test(s) or test group(s) you would like to run, and click Run tests.'),
- );
-
- $form['tests']['table'] = array(
- '#theme' => 'simpletest_test_table',
- );
-
- // Generate the list of tests arranged by group.
- $groups = simpletest_test_get_all();
- 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',
- '#collapsible' => FALSE,
- '#collapsed' => FALSE,
- '#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;
-}
-
-/**
- * Returns HTML for a test list generated by simpletest_test_form() into a table.
- *
- * @param $variables
- * An associative array containing:
- * - table: A render element representing the table.
- *
- * @ingroup themeable
- */
-function theme_simpletest_test_table($variables) {
- $table = $variables['table'];
-
- drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css');
- drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js');
-
- // Create header for test selection table.
- $header = array(
- theme('table_select_header_cell'),
- 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(
- theme('image', array('path' => 'misc/menu-collapsed.png', 'alt' => t('Expand'), 'title' => t('Expand'))) . ' (' . t('Expand') . ')',
- theme('image', array('path' => 'misc/menu-expanded.png', 'alt' => t('Collapse'), 'title' => t('Collapse'))) . ' (' . t('Collapse') . ')',
- ),
- );
-
- // Cycle through each test group and create a row.
- $rows = array();
- foreach (element_children($table) as $key) {
- $element = &$table[$key];
- $row = array();
-
- // 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)));
-
- // 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' => ' ' .
- '',
- 'style' => 'font-weight: bold;'
- );
-
- $row[] = ' ';
-
- $rows[] = array('data' => $row, 'class' => array('simpletest-group'));
-
- // Add individual tests to group.
- $current_js = array(
- 'testClass' => $test_class . '-test',
- 'testNames' => array(),
- 'imageDirection' => $image_index,
- 'clickActive' => FALSE,
- );
-
- // Sorting $element by children's #title attribute instead of by class name.
- uasort($element, '_simpletest_sort_by_title');
-
- // Cycle through each test within the current group.
- foreach (element_children($element) as $test_name) {
- $test = $element[$test_name];
- $row = array();
-
- $current_js['testNames'][] = $test['#id'];
-
- // Store test title and description so that checkbox won't render them.
- $title = $test['#title'];
- $description = $test['#description'];
-
- unset($test['#title']);
- unset($test['#description']);
-
- // Test name is used to determine what tests to run.
- $test['#name'] = $test_name;
-
- $row[] = drupal_render($test);
- $row[] = theme('indentation', array('size' => 1)) . '';
- $row[] = '
' . $description . '
';
-
- $rows[] = array('data' => $row, 'class' => array($test_class . '-test', ($collapsed ? 'js-hide' : '')));
- }
- $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 '' . t('No tests to display.') . '';
- }
- else {
- return theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'simpletest-form-table')));
- }
-}
-
-/**
- * Sort element by title instead of by class name.
- */
-function _simpletest_sort_by_title($a, $b) {
- // This is for parts of $element that are not an array.
- if (!isset($a['#title']) || !isset($b['#title'])) {
- return 1;
- }
-
- return strcasecmp($a['#title'], $b['#title']);
-}
-
-/**
- * Run selected tests.
- */
-function simpletest_test_form_submit($form, &$form_state) {
- // Get list of tests.
- $tests_list = array();
- 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)) {
- $tests_list[] = $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');
- }
-}
-
-/**
- * Test results form for $test_id.
- */
-function simpletest_result_form($form, &$form_state, $test_id) {
- // Make sure there are test results to display and a re-run is not being performed.
- $results = array();
- if (is_numeric($test_id) && !$results = simpletest_result_get($test_id)) {
- drupal_set_message(t('No test results to display.'), 'error');
- drupal_goto('admin/config/development/testing');
- return $form;
- }
-
- // Load all classes and include CSS.
- drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css');
-
- // Keep track of which test cases passed or failed.
- $filter = array(
- 'pass' => array(),
- 'fail' => array(),
- );
-
- // Summary result fieldset.
- $form['result'] = array(
- '#type' => 'fieldset',
- '#title' => t('Results'),
- );
- $form['result']['summary'] = $summary = array(
- '#theme' => 'simpletest_result_summary',
- '#pass' => 0,
- '#fail' => 0,
- '#exception' => 0,
- '#debug' => 0,
- );
-
- // Cycle through each test group.
- $header = array(t('Message'), t('Group'), t('Filename'), t('Line'), t('Function'), array('colspan' => 2, 'data' => t('Status')));
- $form['result']['results'] = array();
- foreach ($results as $group => $assertions) {
- // Create group fieldset with summary information.
- $info = call_user_func(array($group, 'getInfo'));
- $form['result']['results'][$group] = array(
- '#type' => 'fieldset',
- '#title' => $info['name'],
- '#description' => $info['description'],
- '#collapsible' => TRUE,
- );
- $form['result']['results'][$group]['summary'] = $summary;
- $group_summary = &$form['result']['results'][$group]['summary'];
-
- // Create table of assertions for the group.
- $rows = array();
- foreach ($assertions as $assertion) {
- $row = array();
- $row[] = $assertion->message;
- $row[] = $assertion->message_group;
- $row[] = basename($assertion->file);
- $row[] = $assertion->line;
- $row[] = $assertion->function;
- $row[] = simpletest_result_status_image($assertion->status);
-
- $class = 'simpletest-' . $assertion->status;
- if ($assertion->message_group == 'Debug') {
- $class = 'simpletest-debug';
- }
- $rows[] = array('data' => $row, 'class' => array($class));
-
- $group_summary['#' . $assertion->status]++;
- $form['result']['summary']['#' . $assertion->status]++;
- }
- $form['result']['results'][$group]['table'] = array(
- '#theme' => 'table',
- '#header' => $header,
- '#rows' => $rows,
- );
-
- // Set summary information.
- $group_summary['#ok'] = $group_summary['#fail'] + $group_summary['#exception'] == 0;
- $form['result']['results'][$group]['#collapsed'] = $group_summary['#ok'] && !$group_summary['#debug'];
-
- // Store test group (class) as for use in filter.
- $filter[$group_summary['#ok'] ? 'pass' : 'fail'][] = $group;
- }
-
- // Overal summary status.
- $form['result']['summary']['#ok'] = $form['result']['summary']['#fail'] + $form['result']['summary']['#exception'] == 0;
-
- // Actions.
- $form['#action'] = url('admin/config/development/testing/results/re-run');
- $form['action'] = array(
- '#type' => 'fieldset',
- '#title' => t('Actions'),
- '#attributes' => array('class' => array('container-inline')),
- '#weight' => -11,
- );
-
- $form['action']['filter'] = array(
- '#type' => 'select',
- '#title' => 'Filter',
- '#options' => array(
- 'all' => t('All (@count)', array('@count' => count($filter['pass']) + count($filter['fail']))),
- 'pass' => t('Pass (@count)', array('@count' => count($filter['pass']))),
- 'fail' => t('Fail (@count)', array('@count' => count($filter['fail']))),
- ),
- );
- $form['action']['filter']['#default_value'] = ($filter['fail'] ? 'fail' : 'all');
-
- // Catagorized test classes for to be used with selected filter value.
- $form['action']['filter_pass'] = array(
- '#type' => 'hidden',
- '#default_value' => implode(',', $filter['pass']),
- );
- $form['action']['filter_fail'] = array(
- '#type' => 'hidden',
- '#default_value' => implode(',', $filter['fail']),
- );
-
- $form['action']['op'] = array(
- '#type' => 'submit',
- '#value' => t('Run tests'),
- );
-
- $form['action']['return'] = array(
- '#type' => 'link',
- '#title' => t('Return to list'),
- '#href' => 'admin/config/development/testing',
- );
-
- if (is_numeric($test_id)) {
- simpletest_clean_results_table($test_id);
- }
-
- return $form;
-}
-
-/**
- * Re-run the tests that match the filter.
- */
-function simpletest_result_form_submit($form, &$form_state) {
- $pass = $form_state['values']['filter_pass'] ? explode(',', $form_state['values']['filter_pass']) : array();
- $fail = $form_state['values']['filter_fail'] ? explode(',', $form_state['values']['filter_fail']) : array();
-
- if ($form_state['values']['filter'] == 'all') {
- $classes = array_merge($pass, $fail);
- }
- else if ($form_state['values']['filter'] == 'pass') {
- $classes = $pass;
- }
- else {
- $classes = $fail;
- }
-
- if (!$classes) {
- $form_state['redirect'] = 'admin/config/development/testing';
- return;
- }
-
- $form_state_execute = array('values' => array());
- foreach ($classes as $class) {
- $form_state_execute['values'][$class] = 1;
- }
-
- simpletest_test_form_submit(array(), $form_state_execute);
- $form_state['redirect'] = $form_state_execute['redirect'];
-}
-
-/**
- * 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
- */
-function theme_simpletest_result_summary($variables) {
- $form = $variables['form'];
- return '
' . _simpletest_format_summary_line($form) . '
';
-}
-
-/**
- * Get test results for $test_id.
- *
- * @param $test_id The test_id to retrieve results of.
- * @return Array of results grouped by test_class.
- */
-function simpletest_result_get($test_id) {
- $results = db_select('simpletest')
- ->fields('simpletest')
- ->condition('test_id', $test_id)
- ->orderBy('test_class')
- ->orderBy('message_id')
- ->execute();
-
- $test_results = array();
- foreach ($results as $result) {
- if (!isset($test_results[$result->test_class])) {
- $test_results[$result->test_class] = array();
- }
- $test_results[$result->test_class][] = $result;
- }
- return $test_results;
-}
-
-/**
- * Get the appropriate image for the status.
- *
- * @param $status Status string, either: pass, fail, exception.
- * @return HTML image or false.
- */
-function simpletest_result_status_image($status) {
- // $map does not use drupal_static() as its value never changes.
- static $map;
-
- if (!isset($map)) {
- $map = array(
- 'pass' => theme('image', array('path' => 'misc/watchdog-ok.png', 'alt' => t('Pass'))),
- 'fail' => theme('image', array('path' => 'misc/watchdog-error.png', 'alt' => t('Fail'))),
- 'exception' => theme('image', array('path' => 'misc/watchdog-warning.png', 'alt' => t('Exception'))),
- 'debug' => theme('image', array('path' => 'misc/watchdog-warning.png', 'alt' => t('Debug'))),
- );
- }
- if (isset($map[$status])) {
- return $map[$status];
- }
- return FALSE;
-}
-
-/**
* Provides settings form for SimpleTest variables.
*/
function simpletest_settings_form($form, &$form_state) {
Index: scripts/run-tests.sh
===================================================================
RCS file: /cvs/drupal/drupal/scripts/run-tests.sh,v
retrieving revision 1.40
diff -u -r1.40 run-tests.sh
--- scripts/run-tests.sh 15 Jan 2010 10:51:02 -0000 1.40
+++ scripts/run-tests.sh 21 Apr 2010 04:25:15 -0000
@@ -48,7 +48,7 @@
}
// Load SimpleTest files.
-$groups = simpletest_test_get_all();
+$groups = simpletest_php_get_all();
$all_tests = array();
foreach ($groups as $group => $tests) {
$all_tests = array_merge($all_tests, array_keys($tests));
Index: modules/simpletest/simpletest.inc2
===================================================================
RCS file: modules/simpletest/simpletest.inc2
diff -N modules/simpletest/simpletest.inc2
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/simpletest.inc2 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,581 @@
+/**
+ * List tests arranged in groups that can be selected and run.
+ */
+function simpletest_test_form($form) {
+ $form['tests'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Tests'),
+ '#description' => t('Select the test(s) or test group(s) you would like to run, and click Run tests.'),
+ );
+
+ $form['tests']['table'] = array(
+ '#theme' => 'simpletest_test_table',
+ );
+
+ // Generate the list of tests arranged by group.
+ $groups = simpletest_test_get_all();
+ 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',
+ '#collapsible' => FALSE,
+ '#collapsed' => FALSE,
+ '#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;
+}
+
+/**
+ * Returns HTML for a test list generated by simpletest_test_form() into a table.
+ *
+ * @param $variables
+ * An associative array containing:
+ * - table: A render element representing the table.
+ *
+ * @ingroup themeable
+ */
+function theme_simpletest_test_table($variables) {
+ $table = $variables['table'];
+
+ drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css');
+ drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js');
+
+ // Create header for test selection table.
+ $header = array(
+ theme('table_select_header_cell'),
+ 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(
+ theme('image', array('path' => 'misc/menu-collapsed.png', 'alt' => t('Expand'), 'title' => t('Expand'))) . ' (' . t('Expand') . ')',
+ theme('image', array('path' => 'misc/menu-expanded.png', 'alt' => t('Collapse'), 'title' => t('Collapse'))) . ' (' . t('Collapse') . ')',
+ ),
+ );
+
+ // Cycle through each test group and create a row.
+ $rows = array();
+ foreach (element_children($table) as $key) {
+ $element = &$table[$key];
+ $row = array();
+
+ // 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)));
+
+ // 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' => ' ' .
+ '',
+ 'style' => 'font-weight: bold;'
+ );
+
+ $row[] = ' ';
+
+ $rows[] = array('data' => $row, 'class' => array('simpletest-group'));
+
+ // Add individual tests to group.
+ $current_js = array(
+ 'testClass' => $test_class . '-test',
+ 'testNames' => array(),
+ 'imageDirection' => $image_index,
+ 'clickActive' => FALSE,
+ );
+
+ // Sorting $element by children's #title attribute instead of by class name.
+ uasort($element, '_simpletest_sort_by_title');
+
+ // Cycle through each test within the current group.
+ foreach (element_children($element) as $test_name) {
+ $test = $element[$test_name];
+ $row = array();
+
+ $current_js['testNames'][] = $test['#id'];
+
+ // Store test title and description so that checkbox won't render them.
+ $title = $test['#title'];
+ $description = $test['#description'];
+
+ unset($test['#title']);
+ unset($test['#description']);
+
+ // Test name is used to determine what tests to run.
+ $test['#name'] = $test_name;
+
+ $row[] = drupal_render($test);
+ $row[] = theme('indentation', array('size' => 1)) . '';
+ $row[] = '
' . $description . '
';
+
+ $rows[] = array('data' => $row, 'class' => array($test_class . '-test', ($collapsed ? 'js-hide' : '')));
+ }
+ $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 '' . t('No tests to display.') . '';
+ }
+ else {
+ return theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'simpletest-form-table')));
+ }
+}
+
+/**
+ * Sort element by title instead of by class name.
+ */
+function _simpletest_sort_by_title($a, $b) {
+ // This is for parts of $element that are not an array.
+ if (!isset($a['#title']) || !isset($b['#title'])) {
+ return 1;
+ }
+
+ return strcasecmp($a['#title'], $b['#title']);
+}
+
+/**
+ * Actually runs tests.
+ *
+ * @param $test_list
+ * List of tests to run.
+ * @param $reporter
+ * Which reporter to use. Allowed values are: text, xml, html and drupal,
+ * drupal being the default.
+ */
+function simpletest_run_tests($test_list, $reporter = 'drupal') {
+ cache_clear_all();
+ $test_id = db_insert('simpletest_test_id')
+ ->useDefaults(array('test_id'))
+ ->execute();
+
+ // Clear out the previous verbose files.
+ file_unmanaged_delete_recursive(file_directory_path() . '/simpletest/verbose');
+
+ // Get the info for the first test being run.
+ $first_test = array_shift($test_list);
+ $first_instance = new $first_test();
+ array_unshift($test_list, $first_test);
+ $info = $first_instance->getInfo();
+
+ $batch = array(
+ 'title' => t('Running tests'),
+ 'operations' => array(
+ array('_simpletest_batch_operation', array($test_list, $test_id)),
+ ),
+ 'finished' => '_simpletest_batch_finished',
+ 'progress_message' => '',
+ 'css' => array(drupal_get_path('module', 'simpletest') . '/simpletest.css'),
+ 'init_message' => t('Processing test @num of @max - %test.', array('%test' => $info['name'], '@num' => '1', '@max' => count($test_list))),
+ );
+ batch_set($batch);
+
+ module_invoke_all('test_group_started');
+
+ return $test_id;
+}
+
+/**
+ * Batch operation callback.
+ */
+function _simpletest_batch_operation($test_list_init, $test_id, &$context) {
+ // Get working values.
+ if (!isset($context['sandbox']['max'])) {
+ // First iteration: initialize working values.
+ $test_list = $test_list_init;
+ $context['sandbox']['max'] = count($test_list);
+ $test_results = array('#pass' => 0, '#fail' => 0, '#exception' => 0, '#debug' => 0);
+ }
+ else {
+ // Nth iteration: get the current values where we last stored them.
+ $test_list = $context['sandbox']['tests'];
+ $test_results = $context['sandbox']['test_results'];
+ }
+ $max = $context['sandbox']['max'];
+
+ // Perform the next test.
+ $test_class = array_shift($test_list);
+ $test = new $test_class($test_id);
+ $test->run();
+ $size = count($test_list);
+ $info = $test->getInfo();
+
+ module_invoke_all('test_finished', $test->results);
+
+ // Gather results and compose the report.
+ $test_results[$test_class] = $test->results;
+ foreach ($test_results[$test_class] as $key => $value) {
+ $test_results[$key] += $value;
+ }
+ $test_results[$test_class]['#name'] = $info['name'];
+ $items = array();
+ foreach (element_children($test_results) as $class) {
+ array_unshift($items, '