Testing Batch API usage with Simpletest I've written a module that reads a csv of user records and imports them into Drupal 6 using the Batch API. The Batch API operations callback basically just does a user_save(). It works fine when I test it manually. I'm now writing a SimpleTest to verify it.

What I've found is that when I run my test (which extends DrupalWebTestCase), it actually creates new users in my primary Drupal's tables, rather than into the "simpletest" prefixed tables. I suspect this has something to do with the combination of SimpleTest and the Batch API.

Has anyone experienced this before?

SimpleTest 6.x-2.11
Drupal 6.22

Edit: Adding a very simple test case that duplicates the problem. After running the SimpleTest, my primary Drupal site will have 3 new users (u1, u2, u3) created in it. The test will fail, because no users will be created in the 'simpletest*' prefixed tables.

Module code:

function user_import_batch($user_data) {
  $batch = array(
    'title' =&gt; t('Importing users'),
    'operations' =&gt; array(
      array('userimport_process', array($user_data))
    ),
    'progress_message' =&gt; '',
    'finished' =&gt; 'userimport_finished',
  );
  batch_set($batch);
}

function userimport_process($user_data, &amp;$context) {
  // Initialize
  if (empty($context['sandbox']['progress'])) {
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['max'] = count($user_data);
    $context['results'] = array();
  }

  // Process max 20 users at a time
  $processed = 0;
  while ($context['sandbox']['progress'] &lt; $context['sandbox']['max'] &amp;&amp; $processed &lt; 20) {
    $index = $context['sandbox']['progress'];

    // create user
    $account = user_save('', $user_data[$index]);

    $context['sandbox']['progress']++;
    $processed++;
  }
  $context['sandbox']['import_object'] = serialize($Import);

  // Finished yet?
  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  }
}


Simpletest code:

class ImportTestCase extends DrupalWebTestCase {
  protected $privileged_user;

  public static function getInfo() {
    return array(
      'name' =&gt; 'User Import Test',
      'description' =&gt; 'Test',
      'group' =&gt; 'User Import Test',
    );
  }

  public function setUp() {
    parent::setUp();

    // Create and log in our privileged user.
    $permissions = array(
      'administer users',
    ); 
    $this-&gt;privileged_user = $this-&gt;drupalCreateUser($permissions); // user id 3
    $this-&gt;drupalLogin($this-&gt;privileged_user);
  }

   public function testAddUsers() {
     // import 3 users
     $user_data = array(
       array(
         'name' =&gt; 'u1',
         'mail' =&gt; 'u1@example.com',
         'pass' =&gt; 'password'
       ),
       array(
         'name' =&gt; 'u2',
         'mail' =&gt; 'u2@example.com',
         'pass' =&gt; 'password'
       ),
       array(
         'name' =&gt; 'u3',
         'mail' =&gt; 'u3@example.com',
         'pass' =&gt; 'password'
       ),
     );

     user_import_batch($user_data);

     // verify that the users have been created
     // this will fail, as the users will be created in the host site that is running the SimpleTest
     $imported_count = db_result(db_query('SELECT count(uid) FROM {users} WHERE name LIKE "u1" OR name LIKE "u2" OR name LIKE "u3"'));
     $this-&gt;assertEqual(count($user_data), $imported_count, 'Imported users appear in users table. Found ' . $imported_count);
   }
}
Running batch API in tests should work just fine, although there is an issue with the testbot.

Make sure you are always using curly braces for your tables, that's the usual issue when something like this happens. So for example SELECT * FROM {node}.

Edit: 

Two things wrong with your code, as written in the comments.


You are not calling batch_process() in your code, so the batch is never executed within the tests.
My initial answer was not 100% correct. You can not trigger batch runs directly within your test code. A batch requires direct interaction with the browser and it is not possible to run tested batches (simpletest is already running as a batch run). What you need to do is create a test module, implement hook_menu() with a page callback and then call batch_set()/batch_process() there.