Testing times

Over the past week or two I've spent my time working on a Drupal install profile. It uses a custom theme, a bunch of features and a set of modules that allows us to use Aegir to quickly provision a standard website for research centres and projects and associated with our university faculty.

To make sure this install profile keeps working as we make incremental improvements to it, I decided it would be nice to have some tests. For instance, to check that the correct theme is enabled, that the various roles defined in the features we use have the correct level of access to the nodes defined there as well and that blocks are placed in the correct regions with the correct visibility settings.

Unfortunately, the default DrupalWebTestCase class doesn't run profile install tasks, so my tests all failed horribly no matter what I did. 

However, a bit of googling found a blog about unit testing an install profile by Steven Merril from the then Treehouse Agency.

It adds a bit of code to call the profile install tasks in the setUp() function and after I created by own WebTestCase class and added the code, my install task hook was called.

However, all tests kept failing!

In our install profile, we return a Batch API array containing lots of tasks that need to be run at installation time, so that's what the extra code in the test case did too. Return an array of tasks.

Unfortunately it has no smarts to actually execute any of the tasks in that array, so none of the configuration happens.

A bit more googling found no existing solution to this problem, part from the suggestion to rewrite the install profile and perform all our tasks in hook_install() or hook_enable() instead. Having switched to hook_install_tasks() because using hook_install() caused dependency problems, I wasn't about to follow that advice.

Instead, I decided to run the install batch functions in the test class. That lead to some hilarity, as the test process itself is a batch and simply calling batch_set() to add the profile tasks interferes with that, causing the tests to not finish running. Oops.

Since our install tasks don't run for a very long time, I decided I could probably just iterate over the batch API array and call each function in turn. To make sure it doesn't hit the PHP execution timeout limit, it lives on borrowed time through drupal_set_time_limit().

The test class I use is attached as profile_web_test_class.php and happily, that seems to work :-)

And node permissions?

Another problem I ran into was that the drupalCreateUser() function to create test dummies in DrupalWebTestCase doesn't allow you to create users with a specified existing role. Instead, it creates users with randomly generated roles based on permissions you pass to the function.

Since my install profile creates roles with specific permissions whose access I want to test, I needed a function that returns users with those specific roles assigned. Though I did find an issue asking for such functionality in the issue queue, I didn't find a class that implements such a beast.

So for your enjoyment, please find attached role_node_access_class.php.

Comments