Using Mink in PHPUnit

First published at Tuesday, 5 April 2016

This blog post has first been published in the Qafoo blog and is duplicated here since I wrote it or participated in writing it.

Warning: This blog post is more then 7 years old – read and use with care.

Using Mink in PHPUnit

Another day for a short PHPUnit trick. If you want to use PHPunit to control a browser for functional or acceptence tests, then you can easily do this using the Mink library. Mink is well known from the Behat community to facilitate Behaviour-Driven Development (BDD), but it is a standalone library that can be used with PHPUnit just as easily.

This is more flexible than using dedicated browser abstractions such as Selenium directly from PHPunit, because you can switch between different implementations or even run tests with multiple implementations using the same code base.

To start install Mink into your PHP project using Composer:

$ composer require behat/mink behat/mink-goutte-driver --dev

This will install Mink and the Guzzle/Goutte based Driver to crawl your site using a very simple cURL based browser abstraction.

Lets start using it for a simple PHPUnit test that verifies Wikipedia Search:

<?php class WikipediaTest extends \PHPUnit_Framework_TestCase { public function testSearch() { $baseUrl = ''; $driver = new \Behat\Mink\Driver\GoutteDriver(); $session = new \Behat\Mink\Session($driver); $session->start(); $session->visit($baseUrl); $page = $session->getPage(); $page->fillField('search', 'PHP'); $page->pressButton('searchButton'); $content = $session->getPage()->getContent(); $this->assertContains('PHP: Hypertext Preprocessor', $content); $this->assertContains('Rasmus Lerdorf', $content); } }

Setting up the Driver and Session over and over again can become quite complicated, lets introduce a reusable trait:

<?php trait MinkSetup { private $minkBaseUrl; private $minkSession; /** * @before */ public function setupMinkSession() { $this->minkBaseUrl = isset($_SERVER['MINK_BASE_URL']) ? $_SERVER['MINK_BASE_URL'] : 'http://localhost:8000'; $driver = new \Behat\Mink\Driver\GoutteDriver(); $this->minkSession= new \Behat\Mink\Session($driver); $this->minkSession->start(); } public function getCurrentPage() { return $this->minkSession->getPage(); } public function getCurrentPageContent() { return $this->getCurrentPage()->getContent(); } public function visit($url) { $this->minkSession->visit($this->minkBaseUrl . $url); } }

The @before annotation is relatively new, it makes sure that the annotated method is called during each test cases setup phase, whenever we use the MinkSetup trait in a test class.

This allows us to write the actual test in a much simpler way:

<?php class WikipediaTest extends \PHPUnit_Framework_TestCase { use MinkSetup; public function testSearch() { $this->visit('/'); $page = $this->getCurrentPage(); $page->fillField('search', 'PHP'); $page->pressButton('searchButton'); $content = $this->getCurrentPageContent(); $this->assertContains('PHP: Hypertext Preprocessor', $content); $this->assertContains('Rasmus Lerdorf', $content); } }

If you followed the MinkSetup implementation, you saw the MINK_BASE_URL environemnt variable. We can configure this from the phpunit.xml configuration:

<?xml version="1.0" ?> <phpunit bootstrap="vendor/autoload.php"> <php> <env name="MINK_BASE_URL"></env> </php> </phpunit>

You can improve this by adding more helper methods onto the MinkSetup trait, for example by closely following the possibilities that Mink provides inside of Behat (See MinkContext).

Subscribe to updates

There are multiple ways to stay updated with new posts on my blog:

And finally you can also subscribe to the mailing list, where every new blog post is also posted.