Quick and Simple Behavioural Driven Development In PHP

Behavioural Driven Development is a big thing today in testing. Ever since the combo of cucumber and capybara became popular with Ruby, PHP decided to follow the footsteps with cuke4php and behat. Then there was also PHPspec following the footsteps of Rspec as well.

I have been using cucumber and capybara for a while and I loved it. However, I found it too cumbersome to use after a while – there were too many steps in between to get BDD to work nicely for me. First of all, I thought it was a good idea to let non technical people write the behaviour in Business Readable DSL, however they couldn’t do it… ended up I had to write them myself. Then I basically needed to duplicate the behaviours in step definitions using the ruby regex. One also need ruby and capybara installed in their machine and pick up some capybara syntax. Organising the cucumber directory structure also requires some extra effort.

I work with a bunch of PHP nerds and is always asking myself how I can cut down the process if I am doing it in PHP. Imagine a fresh PHP guy comes to me, how can I get him up to speed with BDD in the simplest and quickest way possible. So I came up with a simple solution using just PHPUnit and php-webdriver (forked from the facebook php-webdriver). The php-webdriver is neccessary if we want a PHP substitute for capybara. PHPUnit already supports BDD out of the box but I am going to approach it slightly differently.

Step 1. Install PHPUnit and php-webdriver as per link above.

Step 2. Read about BDD if you are new to it.

Step 3. Create the test file. The filename describes the scenario, for example 01_Test_Header_Renders_Correctly.php and 02_Test_Footer_Renders_Correctly.php

Step 4. The function within the test describes the “Given/When/Then”, take 01_Test_Header_Renders_Correctly.php for example


<?php

require_once(dirname(__FILE__) . '/../PHPWebDriver/WebDriver.php');

class ElementsTest extends PHPUnit_Framework_TestCase {
protected static $driver;
protected static $session;

static function setUpBeforeClass() {
self::$driver = new PHPWebDriver_WebDriver();
self::$session = self::$driver->session(); // firefox
self::$session->open("http://www.your_site.com/");
}

static function tearDownAfterClass() {
self::$session->close();
}

public function setUp() {
}

public function tearDown() {
}

function test_GIVEN_the_homepage_WHEN_in_logo_class_THEN_i_should_see_Logo_Text() {
$s = self::$session->element('class name', 'logo-text');
$this->assertEquals($s->text(),'Logo Text');
}

function test_GIVEN_the_homepage_WHEN_in_top_main_menu_THEN_i_should_see_6_items() {
$s = self::$session->elements('xpath', '//ul[@id="menu-main-nav"]/li');
$this->assertEquals(count($s), 6);
}
}
?>

Now run the test in command line,


phpunit --testdox 01_Test_Header_Renders_Correctly.php

and we will see the browser fired up and it will look for the “Logo Text” in the header and make sure that the top menu has 6 items for example. This is the end report:


PHPUnit 3.6.12 by Sebastian Bergmann.

Elements
[x] test GIVEN the homepage WHEN in logo class THEN i should see sales essentials text
[x] test GIVEN the homepage WHEN in top main menu THEN i should see 6 items

You should now see where I’m coming from. We don’t need a special feature file to describe the behaviour – We use the actual function name in the testcase file to do it.

step 5. Now if we run a simple bash script to loop through all the files in the folder, for example


#!/bin/bash
# remember to run the selenium java server first prior running this
# clear the txt
if [ -f result.txt ]
then
rm result.txt
fi
# now run the test
for i in *.php
do
echo "$i :" >> result.txt
phpunit --testdox $i >> result.txt
echo "-------------------------------------" >> result.txt
done;

# now format the result nicely
sed -i 's/PHPUnit 3.6.12 by Sebastian Bergmann.//g' result.txt
sed -i 's/^Elements$//g' result.txt
sed -i '/^$/d' result.txt
sed -i 's/\] test /\] /g' result.txt


This is the nice result.txt that the bash script will produce:


01_Test_Header_Renders_Correctly.php :
[x] GIVEN the homepage WHEN in logo class THEN i should see Logo text
[x] GIVEN the homepage WHEN in top main menu THEN i should see 6 items
-------------------------------------
02_Test_Footer_Renders_Correctly.php :
[x] GIVEN homepage WHEN i see the footer THEN i should see 7 Links
[x] GIVEN homepage WHEN i see the copyright statement in footer THEN i should see an assessment link
-------------------------------------
03_Test_Homepage_Renders_Correctly.php :
[x] GIVEN homepage WHEN i look at the title THEN it should contains high performance Site Development
[x] GIVEN homepage WHEN i look at jquery slider THEN i should see a h2 why us
[x] GIVEN homepage WHEN i look at bottom right THEN i should see blog entries
-------------------------------------
04_Test_AboutUs_Renders_Correctly.php :
[x] GIVEN about us page WHEN i look at the left menu THEN i should see 4 Item
-------------------------------------
05_Test_Subscription_Page_Works.php :
[x] GIVEN subscription page WHEN i submit the blog form without entering anything THEN i should see an error
[x] Given subscription page WHEN i submit the enews form without entering anything THEN i should see an error
-------------------------------------


Step 6. If you don’t see a [x], you know that the test has failed. You know exactly which file has failed and you can fix the error.

I hope the above method is simple enough to understand. Hope you enjoy reading this article.

Cheers.

Like it.? Share it:
Tags:

One Response to Quick and Simple Behavioural Driven Development In PHP

  1. PHP Development

    Great PHP Development post…