Create Simple Tests for Drupal Features

This article covers how to use the SimpleTest framework with a feature made using the Features module. Most of the advice here applies to anyone who is just getting started with SimpleTest and Drupal automated testing.

Since the Meetings module is almost ready for a stable release, I was forced to quickly realize how important a testing suite is. Until the module has a wide user base who is willing to test the module for me, it is up to me to do all the testing. Considering all the different states the module can be in (organic groups enabled, meeting owner logged in, various permissions, etc.) this quickly becomes an overwhelmeing task.

I dove into the SimpleTest framework to automate my tests in Drupal. It’s a very robust set of tools and it doesn’t take too long to get started with. Unfortunately, I got caught up on a few small points that I ended up wasting hours on. It was particularly difficult for me because I was releasing a feature, not a standard module. The differences are small, but they were enough to slow me down for a while.

After installing SimpleTest, patching Drupal 6.x core, and installing the Examples module, I started reading through the fantastic SimpleTest tutorial. Below are the “gotchas” that I encountered that prevented me from actually writing tests.

Gotcha #1: Module Dependencies

The first problem I encountered with the setUp() function of the module. My function originally looked like this (INCORRECT CODE):

public function setUp() {
  parent::setUp('meetings');
}

I was under the impression that this would automatically enable all of the dependencies of my feature. I was mistaken. In fact, you need to explicitly list all of the dependencies of your feature and list them in the order that you would enable them in the visual interface. For example, date_api must be listed before date because date depends on date_api. The correct code is as follows:

public function setUp() {
// Must include every single module that Meetings relies on
  parent::setUp(
    'content',
    'ctools',
    'date_api',
    'date',
    'date_timezone',
    'date_popup',
    'features',
    'filefield',
    'messaging',
    'notifications',
    'notifications_team',
    'strongarm',
    'text',
    'views',
    'votingapi',

    'meetings'
  );
}

Gotcha #2: Temporary File Directory for SimpleTest

This one isn’t specific to building a feature module, but it did hang me up for a while.

For one reason or another, SimpleTest wasn’t able to create a directory to story temporary files related to the tests. Perhaps this was because my permissions were incorrect, but after getting enough file_put_contents() errors, I did the following:

cd directory-of-your-drupal-site
cd sites/default
mkdir files
mkdir files/simpletest
mkdir files/simpletest/verbose
chmod -R 0777 files

Gotcha #3: features_rebuild()

I’m not actually 100% sure that this is necessary, but while digging through the test suite for features itself, I discovered that the following line is included in the setUp() function of the features tests.

// Run a features rebuild to ensure our feature is fully installed.
features_rebuild();

This did reduce the number of errors I was getting at one point, but now that everything is functioning, commenting out didn’t cause any of my tests to fail.

Gotcha #4: call cache_clear_all()

After talking to Young Hahn, the maintainer of features, I learned that some elements of a feature may not be loaded as expected in a SimpleTest environment because of various caching issues. I threw in a cache_clear_all() into my setUp() to cover all of my bases.

// Clear all caches so everything from the feature is recognized now that it is fully loaded.
cache_clear_all();

Gotcha #5: Permissions reset

Because of the above problem, the permission checking system inside SimpleTest needs it’s cache flushed as well. This arose for me because I was dynamically loading permissions based on the CCK fields in my feature, and since those fields were not loaded when SimpleTest did it’s initial setUp(), they permissions needed to be reloaded before I could use drupalCreateUser() (which does a permissions check along the way). Until I did this, I would get Invalid permission edit meeting purpose and so on for each field that I was adding a permission for.

To for the reset of the permissions, I added this line to my setUp() (before creating any users):

// Force a reset of the internal SimpleTest permission list cache now that the feature is fully loaded.
$this->checkPermissions(array('access content'), TRUE);

I am sure there are other systems within SimpleTest that have caching problems, so keep an eye out if you are experiencing problems. Check in drupal_web_test_case.php to see if there is any caching involved.

Other SimpleTest tips

Here are some resources I found helpful:

Make sure you turn on verbose mode in admin/build/testing/settings. This will automatically save the HTML from any page that SimpleTest calls using drupalGet() or drupalPost().

When you’re at a loss for documentation, just read the inline documentation in drupal_web_test_case.php. That’s the closest you’re going to get to API docuemtnation until api.drupal.org supports documentation inside classes.

When you need to troubleshoot your tests as you are making them, the Drupal 6 version of simpletest offers the debug() function. Read more about debug().

Do you have any advice on using SimpleTest and Features? Post them in the comments.

3 comments

  1. Hi. Thank you for the great article. I try to implement same thing for d7 simpletest but failed. Do you have experience with d7 and current version of the features?

    I have filed an issue https://drupal.org/node/1217340

    Thanks a lot!

  2. There are great informative comments made throughout website.

  3. This post is money. I have referenced it several times building simple tests and have ending up using all of the suggestion. Thanks for you help.

Leave a Reply