Behat testing with PhantomJS and Robo Task Runner
Stack
In this post I’ll give you a quick look on my current behaviour testing workflow within my Symfony2 projects. I’m currently using the following stack for this workflow:
- Symfony2: my PHP weapon of choice
- Behat: testing the behaviour of my applications
- PhantomJS: a fast and headless webkit driver
- Robo Task Runner: a fast PHP task runner
- Composer: a PHP package manager
Symfony2 AcmeDemoBundle
I’m starting this example from an empty Symfony2 project, you can follow the Installing and Configuring Symfony2 Cookbook.
So make sure you can visit the /demo/hello/{name}
path.
Composer
Add the following packages to your composer.json
.
Run composer update
afterwards.
1
2
3
4
5
6
7
8
9
10
11
12
"require": {
...
"behat/behat": "v2.5.2",
"behat/mink": "*",
"behat/symfony2-extension": "v1.1.2",
"behat/mink-extension": "~1.2.0",
"behat/mink-goutte-driver": "*",
"behat/mink-browserkit-driver": "~1.1.0",
"behat/mink-zombie-driver": "*",
"behat/mink-selenium2-driver": "v1.1.1",
"codegyre/robo": "dev-master"
},
or
NPM (Node.js)
I’m using project specific npm packages, so you’ll have to install Node.js.
Create a package.json
file in the root of your project folder with the following content.
Afterwards run npm install
to install the packages.
1
2
3
4
5
6
7
8
9
10
11
{
"name": "AcmeDemoProject",
"version": "1.0.0",
"private": true,
"devDependencies": {
"phantomjs": "~1.9.0"
},
"dependencies": {
...
}
}
Check that it works by issuing ./node_modules/.bin/phantomjs --version
in console.
Behat
To describe your different behat testing configurations create a behat.yml
file in your project folder.
I prefer to place this in the app/config
folder.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# app/config/behat.yml
default:
formatter:
name: pretty,junit,html
parameters:
output_path: null,build/logs/behat,build/behat_report.html
extensions:
Behat\Symfony2Extension\Extension:
mink_driver: true
kernel:
env: dev
debug: true
Behat\MinkExtension\Extension:
base_url: 'http://localhost:8000/app_dev.php'
default_session: selenium2
javascript_session: selenium2
files_path: %behat.paths.base%/../../src/Acme/DemoBundle/Features/files
selenium2:
wd_host: "http://localhost:4444/wd/hub"
browser: "firefox"
capabilities: { "browserName": "firefox", "browser": "firefox", "version": "22" }
paths:
features: features
A simple test
Create a simple feature test in src/Acme/DemoBundle/Features/
.
1
2
3
4
5
6
7
8
9
10
# src/Acme/DemoBundle/Features/hello.feature
Feature: Visit the helo page
In order to visit the helo page
As a normal user
I need to go to that page
Scenario: Visit the helo page
Given I am on "/demo/hello/barry"
Then I should see "Hello barry!"
Symfony2 test client
Enable the test client in the Symfony2 framework config.
Add the following in the config_dev.yml
file.
1
2
3
4
# app/config/config_dev.yml
framework:
test: ~
Robo
A RoboFile.php
describes a series of tasks to execute.
Put this in the root of your project folder.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
// RoboFile.php
class RoboFile extends \Robo\Tasks
{
public $basedir = __DIR__;
public function build()
{
$this->prepare();
$this->behat();
}
public function prepare()
{
$dirs = array(
"build/behat",
"build/logs/behat"
);
$task = $this->taskExecStack()->stopOnFail();
foreach ($dirs as $dir) {
$task->exec("mkdir -p {$dir}");
}
$task->run();
$this->taskComposerInstall()
->optimizeAutoloader()
->run();
$this->npm();
$this->taskExec('app/console assets:install')->run();
$this->taskExec('app/console assetic:dump')->run();
}
private function npm()
{
$this->taskExec('npm')->arg("install")->run();
}
private function behat()
{
$this->taskExec('./node_modules/.bin/phantomjs --webdriver=4444 --webdriver-loglevel=WARNING')
->background()
->run();
$this->taskExec('app/console server:run localhost:8000')
->background()
->run();
$this->taskExec('./bin/behat @AcmeDemoBundle -c app/config/behat.yml')
->run();
}
}
Start testing
Execute your Robot tasks
Footnote
This is just a very basic setup of what you can achieve with those tools. Robo can run all of your tests, so you can add this in your ci environment. You can create your own feature contexts to customize specific actions. This setup isn’t limited to Symfony2 only, you can easily create this in a legacy ‘plain’ PHP project, which I recommend doing.
Thanks for reading
Feel free to leave a comment if you have remarks or like this post