Index: modules/simpletest/simpletest.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v
retrieving revision 1.3
diff -u -p -r1.3 simpletest.module
--- modules/simpletest/simpletest.module	10 May 2008 07:46:22 -0000	1.3
+++ modules/simpletest/simpletest.module	3 Jun 2008 23:45:58 -0000
@@ -82,10 +82,14 @@ function simpletest_entrypoint() {
   simpletest_load();
   drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css', 'module');
   drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js', 'module');
-  $output = drupal_get_form('simpletest_overview_form');
 
-  if (simpletest_running_output()) {
-    return simpletest_running_output() . $output;
+  $output = drupal_get_form('simpletest_overview_form');
+  
+  if (isset($_SESSION['simpletest_reporter'])) {
+    $reporter = unserialize($_SESSION['simpletest_reporter']);
+    $output = $reporter->getOutput() . drupal_get_form('simpletest_overview_form');
+    unset($_SESSION['simpletest_reporter']);
+    return $output;
   }
   else {
     return $output;
@@ -94,6 +98,9 @@ function simpletest_entrypoint() {
 
 function simpletest_running_output($output = NULL) {
   static $o;
+  if (isset($_SESSION['simpletest_results'])) {
+
+  }
   if ($output != NULL) {
     $o = $output;
   }
@@ -280,7 +287,6 @@ function simpletest_run_selected_tests($
       drupal_set_message(t('No test has been selected.'), 'error');
   }
 
-  simpletest_running_output($output);
   return FALSE;
 }
 
@@ -387,7 +393,8 @@ function simpletest_run_tests($test_list
   static $test_running;
   if (!$test_running) {
     $test_running = TRUE;
-    $test = simpletest_get_total_test($test_list);
+    $batch = FALSE;
+    $tests = simpletest_get_total_test($test_list);
     switch ($reporter) {
       case 'text':
         $reporter = &new TextReporter();
@@ -399,22 +406,86 @@ function simpletest_run_tests($test_list
         $reporter = &new HtmlReporter();
         break;
       case 'drupal':
+        $batch = TRUE;
         $reporter = &new DrupalReporter();
         break;
     }
 
     cache_clear_all();
-    $results = $test->run($reporter);
-    $test_running = FALSE;
 
-    switch (get_class($reporter)) {
-      case 'TextReporter':
-      case 'XMLReporter':
-      case 'HtmlReporter':
-        return $results;
-      case 'DrupalReporter':
-        return $reporter->getOutput();
+    if ($batch) {
+      $operations = array();
+      $operations[] = array('_simpletest_batch_operation', array(serialize($tests), serialize($reporter)));
+
+      $batch = array(
+        'title' => t('Running SimpleTests'),
+        'operations' => $operations,
+        'finished' => '_simpletest_batch_finished',
+        'redirect' => 'admin/build/testing',
+        'progressive' => true,
+      );
+      batch_set($batch);
     }
+    else {
+      $results = $tests->run($reporter);
+      $test_running = FALSE;
+      return $results;
+    }
+  }
+}
+
+/**
+ * Batch operation init.
+ */
+function _simpletest_batch_init($reporter, &$context) {
+  $context['results'][] = $reporter;
+  $context['message'] = t('End of initialization');
+  error_log("*** Batch initialization: context = " . serialize($context));
+}
+
+/**
+ * Batch operation callback.
+ */
+function _simpletest_batch_operation($tests, $reporter, &$context) {
+  // Ensure that all classes are loaded.
+  simpletest_get_total_test();
+  $reporter = unserialize( isset($context['sandbox']['reporter']) ? $context['sandbox']['reporter'] : $reporter);
+  $tests = unserialize( isset($context['sandbox']['tests']) ? $context['sandbox']['tests'] : $tests);
+
+  if (!isset($content['sandbox']['progress'])) {
+    $context['sandbox']['progress'] = 0;
+    $context['sandbox']['max'] = $tests->getSize();
+  }
+
+  $test_ran = $tests->runOneByOne($reporter);
+  $context['sandbox']['progress']++;
+
+  $context['message'] = t('Processed test %test', array('%test' => $test_ran));
+
+  // Put back the reporter and tests
+  $context['sandbox']['reporter'] = serialize($reporter);
+  $context['sandbox']['tests'] = serialize($tests);
+
+  // Multistep processing: report progress.
+  if (($size = $tests->getSize()) != 0) {
+    $context['finished'] = 1 - $size / $context['sandbox']['max'];
+  }
+  else {
+    // Finished: save the reporter
+    $context['results'][] = $context['sandbox']['reporter'];
+  }
+}
+
+/**
+ * Batch finished callback.
+ */
+function _simpletest_batch_finished($success, $results, $operations) {
+  $_SESSION['simpletest_reporter'] = array_pop($results);
+  if ($success) {
+    drupal_set_message(t('The tests have finished running.'));
+  }
+  else {
+    drupal_set_message(t('The tests did not successfully finish.'), 'error');
   }
 }
 
@@ -473,5 +544,4 @@ function simpletest_settings() {
   );
 
   return system_settings_form($form);
-
 }
Index: modules/simpletest/test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/test_case.php,v
retrieving revision 1.3
diff -u -p -r1.3 test_case.php
--- modules/simpletest/test_case.php	10 May 2008 06:55:09 -0000	1.3
+++ modules/simpletest/test_case.php	3 Jun 2008 23:45:59 -0000
@@ -390,6 +390,7 @@ class SimpleFileLoader {
 class TestSuite {
   var $_label;
   var $_test_cases;
+  var $_already_ran = false;
 
   /**
    *    Sets the name of the test suite.
@@ -509,6 +510,34 @@ class TestSuite {
     return $reporter->getStatus();
   }
 
+  function runOneByOne(&$reporter) {
+    if (!$this->_already_ran) {
+      $this->_already_ran = true;
+      $reporter->paintGroupStart($this->getLabel(), $this->getSize());
+    }
+    
+    error_log("In runOneByOne, found: ".serialize($this->_test_cases));
+    
+    $test = array_shift($this->_test_cases);
+    if (is_string($test)) {
+      $test = &new $test();
+    }
+    
+    if (is_a($test, 'TestSuite')) {
+      $test_ran = $test->runOneByOne($reporter);
+      array_unshift($this->_test_cases, $test);
+    }
+    else {
+      $test->run($reporter);
+      $test_ran = $test->getLabel();
+    }
+
+    if (count($this->_test_cases) == 0) {
+      $reporter->paintGroupEnd($this->getLabel());
+    }
+    return $test_ran;
+  }
+
   /**
    *    Number of contained test cases.
    *    @return integer     Total count of cases in the group.
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.13
diff -u -p -r1.13 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	3 Jun 2008 19:53:42 -0000	1.13
+++ modules/simpletest/drupal_web_test_case.php	3 Jun 2008 23:46:00 -0000
@@ -198,12 +198,13 @@ class DrupalWebTestCase extends UnitTest
     $form_state['values'] = array('status' => $this->_modules, 'op' => t('Save configuration'));
     drupal_execute('system_modules', $form_state);
 
-    //rebuilding all caches
+    // Rebuilding all caches
     drupal_rebuild_theme_registry();
     node_types_rebuild();
     menu_rebuild();
     cache_clear_all('schema', 'cache');
     module_rebuild_cache();
+    module_list(TRUE);
 
     return $this->assertTrue(module_exists($name), t('@name enabled.', array('@name' =>  $name)), t('Module'));
   }
