Testing Drupal distributions using Behat, Mink, Drupal Extension, and Travis CI
The problem
Imagine never having to click around your website after a site update, worrying that something may have broken. Imagine never getting a call from a client after a site update, telling you that something in fact has broken.
What if instead you could script all the actions that you would normally do by clicking and have those automatically run each time you push new code to your code repository?
All this is possible using Behat, Mink, Drupal Extension, and Travis CI.
This past week I've spent some time creating a proof of concept test suite for a Drupal distribution. I began with the Drupal 7 standard install profile. This will be a walkthrough of the additions I made to add testing to the distribution.
The code
Follow along with the code in my Classic GitHub repository.
The tools
Behat
Behat is a PHP framework for Behaviour Driven Development (BDD). BDD allows for tests that describe the behaviour of a website to be written in English.
Here's an example test (written in the Gherkin syntax) that Behat understands:
Scenario: Logging into the site Given I am logged in as a user with the "authenticated user" role And I am on "/" Then I should not see "User login"
This test uses three step definitions, Given..
, And..
, and Then..
.
Mink
Mink is a PHP framework that abstracts browser simulation. For fast and simple queries we'll use the Goutte PHP web scraper. For testing that our ajax is working correctly we'll use Selenium.
Mink Extension
Mink Extension connects Behat and Mink. It also allows us to write our own step definitions.
Drupal Extension
Drupal Extension connects Behat and Mink to Drupal. It provides a number of step definitions that are useful for working with Drupal sites.
Travis CI
While optional, no testing plan is complete without continuous integration. Travis CI is hosted continuous integration that works with GitHub. It is free for open source projects and recently soft launched their paid private plans. Simply enable testing to your GitHub repository in their UI and include a .travis.yml
file in the root of your project and each time your push your project to GitHub, Travis will run your tests and report back.
Tying it all together
Drush make files
First I copied the Drupal 7 standard profile into a new directory and initialised a git repository. Then I created the following drush make
files:
build-classic.make
drupal-org-core.make
drupal-org.make
To test ajax I added the dialog
contrib module and enabled it in classic.info
. At first I tried testing ajax with the core overlay
module but Selenium couldn't see the popup. It was able to see the dialog
popup just fine.
Install dependencies
Next I created the folder tests/behat/
to store the tests as well as the needed test frameworks. The file composer.json
is used by composer to download and install all the dependenices we'll need.
The following commands will install the dependencies (from the directory tests/behat/
:
curl -s https://getcomposer.org/installer | phpphp composer.phar install
behat.yml
The file behat.yml
is used for configuring Behat.
FeatureContext.php
We've defined a custom step definition for testing ajax. It will wait either 2 seconds or until the id #user-login-dialog
has been loaded. We defined our context class in behat.yml
and it goes in the features/bootstrap/
directory.
Test files
Our test files have the .feature
extension and are placed in the bootstrap/
directory.
I've used tags to tell Mink to run one of the tests with the drush
driver in Drupal Extension (using the @api
tag). I've used another tag to tell Mink to run one of the tests with Selenium to test ajax (using the @javascript
tag).
Selenium
The following commands can be used to download and run Selenium. You need to have Selenium running when you run these tests.
wget http://selenium.googlecode.com/files/selenium-server-standalone-2.25.0.jarjava -jar selenium-server-standalone-2.25.0.jar
Running the tests
From the tests/behat/
directory run ./bin/behat
. Passing tests will be output to the screen in green. Failing tests will be red.
.travis.yml
The .travis.yml
file tells Travis CI how to set up an environment and how to run the tests. The setup includes:
- creating a MySQL database
- downloading
drush
- running
composer install
- running
drush make
to create the Drupal codebase - installing the
classic
distribution - placing a
drush
alias file in the proper place - Using
xvfb
to simulate a window for the browser to run in - running the built in PHP web server
- downloading and running Selenium
- running the tests
Each time I push new commits to GitHub Travis CI will perform these actions and report back whether the tests passed or failed. Travis CI can be configured to only run tests on certain branches.
Summary
There once was a time when we'd need to click around our sites each time new changes were done or module updates were made. Things break. Sometimes it would take hours, days, or even months before it was obvious that something had broke.
Testing with Behat, Mink, and the other tools described here has made it possible to script exactly what we would do when we were clicking around, and have those actions automatically performed before each deployment. What a time saver!