This library is an extension for PHPUnit, that allows to write tests with help of Mink.
This library allows to perform following things:
- use Mink for browser session control
- each test in a test case can use independent browser session
- all tests in a test case can share session between them
- Selenium server connection details are decoupled from tests using them
- perform individual browser configuration for each test in a test case
- support for "Sauce Labs"
- remote code coverage collection
Each mentioned above features is described in more detail below.
- create subclass from
\aik099\PHPUnit\BrowserTestCaseclass - define used browser configurations in static
$browsersproperty of that class - use
$this->getSession()method in your tests to access Mink session
Call $this->getSession() from a test to get running \Behat\Mink\Session object, which is already configured from test configuration.
<?php
use aik099\PHPUnit\BrowserTestCase;
class SessionTest extends BrowserTestCase
{
public function testSession()
{
$session = $this->getSession();
$session->visit('http://www.google.com');
$this->assertTrue($session->getPage()->hasContent('Google'));
}
}It is possible to set individual browser configuration for each test in a test case by creating a \aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration class instance in setUp method of the test case.
<?php
use aik099\PHPUnit\BrowserTestCase;
use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration;
class PerBrowserConfigTest extends BrowserTestCase
{
protected function setUp()
{
// to create regular browser configuration via BrowserConfigurationFactory
$browser = $this->createBrowserConfiguration(array(
// options goes here (optional)
));
// to create "Sauce Labs" browser configuration via BrowserConfigurationFactory
$browser = $this->createBrowserConfiguration(array(
// required
'type' => 'saucelabs',
'api_username' => 'sauce_username',
'api_key' => 'sauce_api_key',
// options (optional) goes here
));
// options can be changed later (optional)
$browser->setHost('selenium_host')->setPort('selenium_port')->setTimeout(30);
$browser->setBrowserName('browser name')->setDesiredCapabilities(array('version' => '6.5'));
$browser->setBaseUrl('http://www.test-host.com');
// set browser configuration to test case
$this->setBrowser($browser);
parent::setUp();
}
}It is possible to define a single browser configuration to be used for each test in test case. This can be done by defining static $browsers class variable as an array, where each item represents a single browser configuration. In that case each of the tests in a test case would be executed using each of defined browser configurations.
<?php
use aik099\PHPUnit\BrowserTestCase;
class CommonBrowserConfigTest extends BrowserTestCase
{
public static $browsers = array(
array(
'host' => 'localhost',
'port' => 4444,
'browserName' => 'firefox',
'baseUrl' => 'http://www.google.com',
),
array(
'host' => 'localhost',
'port' => 4444,
'browserName' => 'chrome',
'baseUrl' => 'http://www.google.com',
),
);
public function testUsingBrowsersArray()
{
echo sprintf("I'm executed using '%s' browser", $this->getBrowser()->getBrowserName());
}
}As a benefit of shared browser configuration, that was described above is an ability to not only share browser configuration, that is used to create Mink session, but to actually share created sessions between all tests in a test case. This can be done by adding sessionStrategy option to browser configuration.
<?php
use aik099\PHPUnit\BrowserTestCase;
class CommonBrowserConfigTest extends BrowserTestCase
{
public static $browsers = array(
array(
'host' => 'localhost',
'port' => 4444,
'browserName' => 'firefox',
'baseUrl' => 'http://www.google.com',
'sessionStrategy' => 'shared',
),
);
}All previous examples demonstrate various ways how browser configuration can be defined, but they all have same downside - server connection details stay hard-coded in test case classes. This could become very problematic if:
- same test cases needs to be executed on different servers (e.g. each developer runs them on his own machine)
- due change of server connection details each test case class needs to be changed
To solve this problem a browser aliases were introduced. Basically a browser alias is predefined browser configuration, that is available in the test case by it's alias. How it can be used:
- create base test case class, by extending BrowserTestCase class in the project with
getBrowserAliasesmethod in it. That method will return an associative array of a browser configurations (array key acts as alias name) - in any place, where browser configuration is defined use
'alias' => 'alias_name_here'instead of actual browser configuration - feel free to override any part of configuration defined in alias
- nested aliases are also supported
<?php
use aik099\PHPUnit\BrowserTestCase;
abstract class BrowserAliasTest extends BrowserTestCase
{
public function getBrowserAliases()
{
return array(
'example_alias' => array(
'host' => 'localhost',
'port' => 4444,
'browserName' => 'firefox',
'baseUrl' => 'http://www.google.com',
),
);
}
}
class ConcreteTest extends BrowserAliasTest
{
public static $browsers = array(
array(
'alias' => 'example_alias',
),
array(
'alias' => 'example_alias',
'browserName' => 'chrome',
),
);
}When using "Sauce Labs" account to perform Selenium server-based testing you need to specify 'type' => 'saucelabs', 'api_username' => '...', 'api_key' => '...' instead of host or port settings. In all other aspects all will work the same as if all tests are running locally.
Browser tests are executed on different machine, then one, where code coverage information is collected (and tests are executed). To solve that problem this library uses remote coverage collection. Following steps needs to be performed before using this feature:
Remote server is web-server, where website used in tests is located.
- Install Xdebug PHP extension on web-server
- Copy
library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.phpinto web-server's DocumentRoot directory. - Include following code before your application bootstraps:
require_once 'RemoteCoverageTool.php';
\aik099\PHPUnit\RemoteCoverage\RemoteCoverageTool::init();This is machine, where PHPUnit tests are being executed.
By default the baseUrl setting from browser configuration is used as the remote code coverage information url. However if a need exists to set alternative url on per-test basis, then place following code in the setUp method of the test case class, that extends BrowserTestCase class:
$this->setRemoteCoverageScriptUrl('http://host/'); // `host` should be replaced with web server's url- each test sets a special cookie on website under test
- when cookie is present, then
RemoteCoverageTool.phpscript collects coverage information and stores it on disk - once test finishes, then
http://host/?rct_mode=outputurl is accessed on remote server, which in turn returns collected coverage information - remote coverage information is then joined with coverage information collected locally on test machine
Each browser configuration consists of the following settings:
host- host, where Selenium Server is located (defaults tolocalhost)port- port, on which Selenium Server is listening for incoming connections (defaults to4444)timeout- connection timeout of the server in seconds (defaults to60)browserName- name of browser to use (e.g.firefox,chrome, etc., defaults tofirefox)desiredCapabilities- parameters, that specify additional browser configuration (e.g. browser version, platform, etc.)baseUrl- base url of website, that is testedsauce- Sauce Labs connection configuration (e.g.array('username' => 'username_here', 'api_key' => 'api_key_here'))
There are also corresponding set and get methods for each of mentioned above settings, that allow to individually change them before test has started (from setUp method).
- Define the dependencies in your
composer.json:
{
"require": {
"aik099/phpunit-mink": "~1.0"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/aik099/phpunit-mink"
},
]
}- Install/update your vendors:
$ curl http://getcomposer.org/installer | php
$ php composer.phar install




