Using PHP’s built-in web server in Behat tests

Behat is a tool for running acceptance tests for your application. If your application is a web application you will need a web server to execute your tests. This is not likely an issue when running your tests locally since you probably have a web server running on the development server that you can use, but when you execute your tests on Travis-CI for instance (you use Travis-CI right? RIGHT?!) it can be cumbersome getting a local Apache up and running for your test suite to use.

Some weeks back I wrote a post showing you how to use PHP’s built in web server in PHPUnit. This post will show you how to do the same for Behat when running your acceptance tests.

To fully understand everything that is mentioned in this post you need some knowledge of how Behat works, so if you have never used the tool before I would recommend skimming the Quick Intro to Behat at first.

I have also created a repository at GitHub with the code you need to be able to get started using PHP’s built in web server in your Behat test suite. This post will explain what the code does.

First, go ahead and clone the repository:

To install Behat you need to use Composer:

Now you should have all you need to execute the Behat test suite. Try to execute the following command:

You should see something like this in your terminal:

The repository you just cloned does not contain any actual code to test, nor any features for Behat to execute, so everything seems to be working as expected.

What has happened behind the scenes when running the above command is that Behat’s feature context spawned a web server as the suite started, and then proceeded to kill it when the suite finished. To achieve this I have some custom code in the feature context class that hooks into two events: @BeforeSuite and @AfterSuite. These are two of many other hooks you can use in your tests. Check out Hooking into the Test Process – Hooks for more info.

First, let’s take a look at the @BeforeSuite code:

The first thing that happens is that we fetch the Behat configuration. The configuration is located in the .behat.yml file and uses the YAML format:

The variables specified is used by Behat when starting the web server. url is the URL you want to use in your tests when accessing the web server. documentRoot is a path to the directory that should be used as a document root. The last parameter, timeout, is how long we want to allow the web server to use in seconds before we can connect to it. If you have a particularly slow machine you might need to set it to more than 1 second.

Now, back to the feature context code. After fetching the configuration we see if something is already running on the host and port combination. If this is the case we will simply throw an exception, halting the test suite.

Next up the script tries to start the web server, and then continues to try to connect to it for the amount of seconds specified in the configuration. If it is unable to connect we will throw another exception, again causing the test suite to abort. If we manage to connect to the web server the suite will continue as expected.

When the test suite have finished executing the tearDown method will be executed:

Now it’s up to you to write feature specifications that actually uses the web server in your tests. I’ll leave that part for you. You’re welcome.

Read more from the Software engineering category