Main content

Testing the Symfony2 app with MinkBundle, PhantomJS and PHPUnit

Shashikant Jagtap

Senior Developer

In this post Shashikant Jagtap, Senior Developer in test working for , shares his experiences setting up with  for the web testing of the application, using PhantomJS based and fixtures.

Please note: All code samples for this post are available on GitHub .

We used a comibination of MinkBundle, PHPUnit, PhantomJS and Doctrine to automate our web tests - this gives a high level of confidence to the whole team when developing an application. As long as testing pyramid is considered, the application should have unit and integration tests which are considered as fast and solid. On top of that, it should also have functional tests which are considered as slow and brittle, but do add value and confidence within the team.

has solid documentation around and it covers both unit and functional testing aspects. However, Symfony2 documentation explains WebTestCase library for functional testing which uses under the hood. The Symfony2 standard edition comes with PHPUnit for unit tests and for functional tests, which doesn't support JavaScript. Using WebTestCase isn't a great approach all the time though, because:

  • The application involves JS & Ajax interactions.
  • We have to test it against different browsers and switch between them.
  • There are different user journeys to be considered while navigating to the pages to fill the forms.

MinkBundle

In order to deal with problems with WebTestCase, we found . It's a Symfony2 bundle which can be used in any Symfony project. There are various benefits Mink can provide:

  • We can choose JS or non JS drivers as Mink has different like Selenium, Zombie, Goutte.
  • We can on the pages and perform some actions. have lots of actions.
  • Mink provides an inbuilt assertion library called which allows us to make smarter assertions.
  • MinkBundle allows us to access containers and use or other similar fixture mechanism.

Setting up MinkBundle in the existing Symfony2 project is pretty easy - basically its a 3 step process:

  1. MinkBundle and Selenium WebDriver dependencies in your file.
  2. Register the bundle in the directory.
  3. Update Kernel configuration in to include Mink config.

We can always set a base URL where we are going to execute tests. Currently its setup for the local host. Now we are ready to use Mink bundle.

Ghost Driver

is a PhantomJS based wrapper around . Mink has various drivers like Selenium, Goutte, Zombie and Sahi, but we can use based GhostDriver to drive tests without launching a browser. Assuming you have installed PhantomJS, then launch GhostDriver on any available port:

$ phantomjs --webdriver=8643

Now GhostDriver is listening to "http://localhost:8643/wd/hub" and we have configured that path in our .

PHPUnit Test Setup

is a cool library to write a unit test and can be used to write acceptance tests using PHP. In order to use PHPUnit with MinkBundle, we can abstract a few details into like:

  • Mink Session setup.
  • Web Assert setup.
  • Fixture Setup using .

Mink has the ability to perform user actions on the page like clicking, filling forms, accept/deny pop-up, scroll up and down etc. There are various we can use to automate browser tasks. Mink has an awesome library called 'WebAssert' which allows us to make various assertions on the browser behaviours. Please have a look at to see the complete details. You can view sample code for BaseMinkPHPUnitTestCase class .

WebAssertProxy

Mink has great assertions which can be used while performing browser actions, but it has a couple of issues while using with PHPUnit.

  • When test fails, it throws an exception rather than error.
  • Mink WebAssert assertions isn’t counted by PHPUnit.

We need to make some amendments to make it play better with PHPUnit. We wrote in order to deal with PHPUnit. We have used to get fixture data loaded in to tests before execution and tear down after test execution. Sample code for the WebAssettProxy is .

Writing & Running Tests

At this stage, we are good to write our first functional tests. We can write our test exactly how we write PHPUnut but will extend to MinkBaseClass. Again, writing tests involves following steps:

  • Load Fixtures.
  • Open Page and perform Action using Mink.
  • Assert elements on pages with WebAssert.
  • Tear Down Fixture.

Simple homepage tests will look like .

In order to run those tests we need to make sure that the  and GhostDriver services are started. We can launch local web server using symfony as:

$ php app/console run:server

And again we can launch GhostDriver as:

$ phantomjs --webdriver=8643

Assuming we have edited 'app/phpunit.dist.xml'. Now we are ready to run our tests using:

$ bin/phpunit -c app

Junit reports are logged if you use the default phpunit configuration, which can be then plugged into the Continuous Integration server. Additionally, you can created separate to run only JS related browser tests.

Conclusion

We can use MinkBundle in the combination of PHPUnit and GhostDriver in order to perform web acceptance testing of JavaScript interactive appplications. Hope you find this setup easy to use.