Pat Shaughnessy

Ribadesella, Spain

Why to use TDD with Drupal

September 02, 2008 · 4 comments

Drupal is a very popular Content Management System (CMS) developed using PHP. It’s a great way to get an interactive, community web site such as a blog or discussion forum up and running quickly without writing any code. But Drupal is a poor choice for general, complex web application development for a few simple reasons:

  1. It doesn’t use a standard, general software architecture such as Model-View-Controller (MVC) like Rails or Struts.
  2. Drupal doesn’t employ or support modern development best practices such as Test Driven Development (TDD) or automated testing more generally. (Exception: the SimpleTest module can provide some automated integration testing using HTTP without opening a real browser.)
  3. While the module API does allow for some customization, it can be easy to get into trouble if your target application is outside of Drupal’s design center. Specifically, you may end up having to modify Drupal’s core code or database schema when Drupal doesn’t behave the way you would like.

A better choice for more general or complex web development would be Ruby on Rails.

If you do need to develop a custom web application using the Drupal framework, you can avoid problems #2 and #3 by using a test driven approach. Instead of simply implementing your custom logic by writing PHP code to the Drupal module API, try pulling your custom code out of Drupal entirely and running it independently of the framework. This will insure that your custom code could someday be run with another web framework and also help you avoid the temptation of modifying Drupal’s core code directly. Of course, you will also get all of the normal benefits of TDD: better design oriented around business requirements, live documentation through executable code, etc.

How to do this? Write tests first using PHPUnit (which fail), then get your tests to pass by implementing the desired behavior using PHP 5 objected oriented code. Lastly, write a “shell” module that calls out to your test driven object oriented PHP code from Drupal. This means your code will be run twice: once from the command line by PHPUnit during development and from your CI process, and again from Drupal to process end user requests in production.

In a series of future posts I'll write a Drupal module using TDD, using a few tips and tricks along the way to get PHPUnit and Drupal to play together nicely.

Tags:

4 responses so far ↓

  • 1 chopp3r // Nov 06, 2008 at 11:27 PM

    I've begun getting a TDD culture started in my workplace where we develop a site using the Drupal CMS. I've pursuaded everyone that PHPUnit is the best test framework for the job and got involved with Jon Wage in working with his Drupal PHPUnit module. I've improved the Drupal PHPUnit module a little and hope to contribute that code back in soon. It bootstraps the Drupal CMS prior to running the tests. I await your next post on getting PHPUnit and Drupal playing together nicely to see what good ideas there are that we can take away.
  • 2 pat // Nov 16, 2008 at 07:44 AM

    Sorry chopp3r since I wrote this in September I haven’t had any time to work on Drupal and have instead been focusing on learning Ruby on Rails. I’ll be sure to post what I have with Drupal and PHPUnit soon… And I’ll take a look at the PHPUnit module when I get a chance. I don’t remember anything like that existing the last time I was doing active Drupal development – sounds like a great idea!

    However, after learning more about testing in Rails and trying things like Mocha, RSpec, Shoulda, etc., I’m thinking now that it would be more useful for Drupal developers to find a way to call PHP from Ruby and take advantage of these frameworks, rather than using PHPUnit. I’ll see if I can work up an example and post it here.

  • 3 fschwiet // Jan 18, 2010 at 01:20 PM

    pat thanks for putting this together. The approach you describe is exactly what I found writing script extensions in another environment. Just curious if you've found a favorite rails-based CMS. I don't know about the idea of testing PHP with tests written from Ruby. Reading Fowler would indicate to me that the test framework should be in the same language that as the system under test.
  • 4 pat // Jan 19, 2010 at 10:38 AM

    Thanks! Nope I haven’t really looked into Rails CMS systems yet; for this blog I use Mephisto which works well enough for my purposes. I’ve also heard good things about Radiant, but haven’t tried it myself. Another new one to look at is Rango.

    And yes I agree: writing unit tests in a language different from the code under test is a bad idea. But integration testing of PHP with a Ruby based tool might work. Using Cucumber + Webrat on Drupal is still on my (long) list of to do items/ideas to look into for this year.

Leave a Comment