Pat Shaughnessy

Ribadesella, Spain

Using transactions in a separate database with Drupal PHPUnit tests

January 19, 2009 · 3 comments

Update April 2009:
I’ve started working with Mark Bennett on phpunit_setup.inc and moved it up to a github repository. Mark has adapted it to work with Drupal 5, and we’re working on a number of other related ideas as well. I’ll post updates here about our progress.

This month I’ve been experimenting with using testing ideas from Ruby on Rails while developing a Drupal module. To read more, see:

If you want to try this out yourself, follow these instructions:

  1. Edit settings.php and use an array of two values for $db_url:

    $db_url["default"] = 'mysql://user:password@localhost/drupal;
    $db_url["test"] = 'mysql://user:password@localhost/drupal_test';
  2. Create a new test database in MySQL:

    CREATE DATABASE drupal_test DEFAULT CHARACTER SET utf8
                                COLLATE utf8_unicode_ci;
  3. Download and save phpunit_setup.inc somewhere in your Drupal application; for example in the “includes” folder.
  4. Include phpunit_setup.inc at the top of each of your PHPUnit test classes. See one of the two articles above for example PHPUnit tests.
  5. Execute your PHPUnit test class from the root folder of your Drupal app:

    $ cd /path/to/your/drupal-site
    $ phpunit YourClass modules/your_module/YourClassFileName.php 
    PHPUnit 3.2.21 by Sebastian Bergmann.
    ..
    Time: 0 seconds
    OK (2 tests)

For more information about how to run PHPUnit with Drupal, see: Writing your first PHPUnit test in Drupal.

Tags:

3 responses so far ↓

  • 1 Matt Butcher // Jan 22, 2009 at 06:12 PM

    I like the PHPUnit + Command line + separate database + transactions combination. I find PHPUnit to be a very good testing framework, since it supports tons of assertions, a robust mock setup, and BDD as well as standard TDD. The separate database seems to me to be verging on essential. I've never been particularly comfortable with storing testing data inside of the main database, and I've never really understood the rationale for the decision (other than ease of development. Rails' testing methodology is very robust, and this is definitely a method worthy of cloning. Transactions are a nice additional feature, too... though something I have less of a strong opinion about. If you're going that route, why not just use in-memory tables and re-create them every time? Very thought provoking articles.
  • 2 Mark Bennett // Mar 27, 2009 at 04:38 AM

    Just wanted to start by saying how much I appreciated this series. I'm an experienced TDD developer who's relatively new to the Drupal framework and have been unsatisfied with my experiencing using SimpleTest. Reading your articles really made me see how it was possible to do TDD in Drupal, so I was disappointed when I realized the code doesn't work on Drupal 5 which my client is currently using. Inspired by your example I've written another include file to backport a few Drupal 6 functions into Drupal 5. I also changed two lines in your phpunit_setup.inc file so it will work with the older database abstraction layer in Drupal 5. You can get all the details on my blog at: http://markbennett.ca/2009/03/bringing-tdd-to-drupal-5/ If you're interested please let me know and I'd be happy to send you my files along with a patch for phpunit_setup.inc. I've tried to include attribution where appropriate. Thank-you!
  • 3 Christopher Hopper // May 27, 2009 at 02:15 AM

    Thanks for the excellent work, Mark and Patt, putting together a solution that will create a clean test database for testing. I'd like to integrate the final approach, with all attributuions, into the PHPUnit Drupal 5 module. Would you like to contribute? I'm using the PHPUnit Drupal module currently to write unit tests for custom Drupal 5 module code where I work. Isolation of the test data is a problem I've not yet solved. The previous PHPUnit Drupal 5 module maintainer had a solution that recreated the database from a dump, but this was slow.

Leave a Comment