Test JavaScript interactions with Behat

Following the series Mercè started and the talks I have been giving I wanted to write a bit more about Behat and some niceties that I learned on the way.

One of the main points people get interested on Behat is not only because you can use natural language to describe and test your application but also because all the tests are able to run in a real browser.

Let’s make an overview of the main pieces available to achieve a broader testing strategy.

Selenium

Automated testing in browsers started to get mainstream with a tool called Selenium that allowed developers to interact with a browser by clicking and typing and then replay that interaction as many times as needed. Selenium evolved to give birth to a component called webdriver that defines a protocol to drive real web browser opening the door to automation.

Why is this relevant to Behat? Because Mink, one of the main components of Behat can talk to Selenium using a driver.

Continuous integration

To give a little context: what we want is to be sure as often as possible that the application behaves as expected. For this goal running the tests only so often is not enough, we need more automation establishing a repetitive process. That means reacting to changes in the code repository and running our tests and assertions against those changes. As we hinted above we are going to need a real browser (not a mock like you can do by using curl and inspecting the html) to run the Javascript that is served along the web page.

In our laptops we have a screen and is easy to run graphical applications like a browser but in a server without a display or graphical environment is a bit more tricky.

Selenium server

The first tool that appeared and the the first that we used was Selenium server. To run properly it needs xvfb to simulate a screen in memory, the Selenium Java server to send commands to the browser and Firefox to render and execute our web application.

This is a big stack of dependencies and it needs control over how to start the different daemons and processes and kill them when you are finished.

PhantomJS

To simplify the stack PhantomJS is a tool that integrates the three components: it renders the page internally (even if it runs with a graphical interface), understands the webdriver commands sent by Mink (we still use the same Selenium2 driver in Behat) and it has a full webkit browser(similar engine to chrome and safari) inside. This will speed up the execution of the tests because we got rid of a lot of overhead. You can even install it with Composer!

Remember that you can swap between the Selenium + Firefox stack and PhantomJS to debug at any moment since they are just services listening on a port of your computer.

Tag the scenarios

By changing the underlying software we gained some speed but such a high level of testing will be slow by definition. The reason for this is because we are trying to get as close as possible to a real world scenario with a full Drupal installation and a full web browser.

To alleviate this situation we can pinpoint the Behat scenarios that need browser execution just by using the @javascript tag on the line before each scenario. The rest of the scenarios will use a fake browser that uses curl.

This a is brief introduction to the most popular tools to automate the process and how they work together. We plan to continue this series with specific configurations on how to make it work on your day to day development. Stay tuned.