Acceptance & Integration Testing With Behat (PHPNw2011)

Preview:

DESCRIPTION

The slides from my talk 'Acceptance and integration Testing Using Behat'. Given at PHPNW11 08/10/11.

Citation preview

Acceptance & Integration

Testing Using Behat

Ben WaineEmail: ben@ben-waine.co.uk

Twitter: @bwaine

Sunday, 9 October 11

Roadmap•Intro To Behaviour Driven Development

•Problems We Are Trying to solve at Sky With BDD

•Behat

•API Testing with Behat

•UI Testing with Behat

•Data Driven Testing

•Is Behat solving our problem?

Sunday, 9 October 11

Me

Sky BetPHP / MySQL Stack

PHPUnit / Selenium / Behat

Software EngineerPHP Developer

Sunday, 9 October 11

BehaviourDriven Development

(BDD)

Sunday, 9 October 11

Behaviour-driven development (BDD) takes the position that you can turn an idea for a requirement into implemented, tested, production-ready code simply and effectively, as long as .... everyone knows what’s going on.

- Dan North

Sunday, 9 October 11

- Drinkwater et al 2011

Writing tests first in a customer friendly language

Sunday, 9 October 11

The Problem

Sunday, 9 October 11

The Business Analyst

Sunday, 9 October 11

The Tester

Sunday, 9 October 11

The Developer

Sunday, 9 October 11

The Problem

Sunday, 9 October 11

Behat

Sunday, 9 October 11

Resistance is futile.......Sunday, 9 October 11

What Does It Test?

ScriptsAPI’s

Web PagesModels

Sunday, 9 October 11

Integration Testing !=

Unit Testing

Sunday, 9 October 11

Anatomy Of A Behat Test

Sunday, 9 October 11

Sunday, 9 October 11

Sunday, 9 October 11

My Amazing PHP Conference Website!

Sunday, 9 October 11

Writing Behat Tests

$ben > cd /path/to/projects/tests$ben > behat --init

Sunday, 9 October 11

Writing Behat Tests

Sunday, 9 October 11

Feature Files

Feature: Home Page When visiting the PHPCon site As a site visitor I need to be able to see what ` conferences are coming up

Sunday, 9 October 11

ScenariosScenario: Get all conferences Given there is conference data in the database When I go to the homepage Then I should see three conferences in a table

Sunday, 9 October 11

ScenariosGiven

(Some Context)

When (Some Event)

Then (The Outcome)

Sunday, 9 October 11

Given (Some Context)

Given there is conference data in the database

Sunday, 9 October 11

When (Some Event)

When I go to the homepage

When I use the findConferences method

When I am on "/index.php"

When I fill in "search-text" with "PHP"

Sunday, 9 October 11

Then (The Outcome)

Then I should see three conferences in a table

Then I should get a array of three conferences

Then I should see "PHPNW"

Sunday, 9 October 11

ConferenceService.feature

Feature: ConferenceService Class In order to display conferences on PHPCon site As a developer I need to be able to retrieve conferences

Scenario: Get all conferences Given there is conference data in the database When I use the findConferences method Then I should get a array of three conferences AND it should contain the conference “PHPNW”

Sunday, 9 October 11

Class Methods & Annotations

Sunday, 9 October 11

/ Everybody Stand Back /

Behat Knows Regular Expressions

Sunday, 9 October 11

Sunday, 9 October 11

Sunday, 9 October 11

Sunday, 9 October 11

Sunday, 9 October 11

Copy and paste these methods into FeatureContext.php

Sunday, 9 October 11

Sunday, 9 October 11

Sunday, 9 October 11

Fill in the Feature Context File public function __construct(array $parameters) { $params = array( 'user' => $parameters['database']['username'], 'password' => $parameters['database']['password'], 'driver' => $parameters['database']['driver'], 'path' => $parameters['database']['dbPath'], );

$con = \Doctrine\DBAL\DriverManager::getConnection($params);

$confMapper = new \PHPCon\Conference\Mapper($con); $confService = new \PHPCon\Conference\Service($confMapper);

$this->service = $confService; }

Sunday, 9 October 11

Fill in the Feature Context File

/** * @Given /^there is conference data in the database$/ */ public function thereIsConferneceDataInTheDatabase() { $fileName = self::$dataDir .

'sample-conf-session-data.sql'; self::executeQueriesInFile($fileName); }

Sunday, 9 October 11

Fill in the Feature Context File

/** * @When /^I use the findConferences method$/ */ public function iUseTheFindConferencesMethod() { $this->result = $this->service->findConferences();

}

Sunday, 9 October 11

Fill in the Feature Context File /** *@Then /^I should get an array of (\d+) conferences$/ */ public function iShouldGetAnArrayOfConferences

($numberOfCons) { assertInternalType('array', $this->result); assertEquals($numberOfCons, count($this->result)); }

Sunday, 9 October 11

/** * @Then /^it should contain the * conference "([^"]*)"$/ */ public function itShouldContainTheConference

($confName) { $names = array();

foreach($this->result as $conf) { $names[$conf->getName()] = true; }

if(!array_key_exists($confName, $names)) { throw new \Exception("Conference "

. $confName . " not found"); } }

Sunday, 9 October 11

Ready to run the tests again.....

Sunday, 9 October 11

Sunday, 9 October 11

Sunday, 9 October 11

Failing Test

Sunday, 9 October 11

Add some application code.....

Sunday, 9 October 11

Sunday, 9 October 11

Sunday, 9 October 11

Sunday, 9 October 11

Passing Test!

Sunday, 9 October 11

What about the UI?

Sunday, 9 October 11

Mink

Sunday, 9 October 11

Mink

Goutte Sahi

Zombie.js

Sunday, 9 October 11

Extend Mink Context

Use Bundled steps to create higher level abstractions.

Includes predefined steps

Sunday, 9 October 11

Back To: My Amazing PHP Conference

Website!

Sunday, 9 October 11

Example

Scenario: View all conferences on the homepage Given there is conference data in the database When I am on "/index.php" Then I should see "PHPNW" in the ".conferences" element And I should see "PHPUK" in the ".conferences" element And I should see "PBC11" in the ".conferences" element

Using Minks Bundled Steps

Sunday, 9 October 11

# features/bootstrap/UIContext.php

use Behat\Behat\Context\ClosuredContextInterface, Behat\Behat\Context\BehatContext, Behat\Behat\Exception\PendingException;

use Behat\Gherkin\Node\PyStringNode, Behat\Gherkin\Node\TableNode;

require_once 'mink/autoload.php';

class UIContext extends Behat\Mink\Behat\Context\MinkContext{

}

class FeatureContext

public function __construct(array $parameters) { $this->useContext('subcontext_alias', new UIContext($parameters));

! // REST OF FEATURE CONSTRUCTOR

}

Sunday, 9 October 11

Sunday, 9 October 11

Sunday, 9 October 11

Sunday, 9 October 11

Sunday, 9 October 11

Powerful Headless UI Testing Out The Box

Sunday, 9 October 11

Scenario: View all conferences on the homepage Given there is conference data in the database When I am on the "home" page Then I should see "PHPNW" in the "conferences" table And I should see "PHPUK" in the "conferences" table And I should see "PBC11" in the "conferences" table

Abstracting your scenario

Sunday, 9 October 11

class UIContext extends Behat\Mink\Behat\Context\MinkContext{ protected $pageList = array( "home" => '/index.php'); protected $elementList = array( "conferences table" => '.conferences');

Mink Feature Context

Sunday, 9 October 11

/** * @When /^I am on the "([^"]*)" page$/ */ public function iAmOnThePage($pageName) {

if(!isset($this->pageList[$pageName])) { throw new Exception( 'Page Name: not in page list'); } $page = $this->pageList[$pageName]; return new When("I am on \"$page\""); }

Sunday, 9 October 11

/** * @Then /^I should see "([^"]*)" in the "([^"]*)"$/ */ public function iShouldSeeInThe($text, $element) { if(!isset($this->elementList[$element])) { throw new Exception( 'Element: ' . $element . ‘not in element list'); } $element = $this->elementList[$element]; return new Then("I should see \"$text\" in then\"$element\" element"); }

Sunday, 9 October 11

Javascript Testing with.....

Sahi

Sunday, 9 October 11

Back To: My Amazing PHP Conference

Website!

Sunday, 9 October 11

@javascriptScenario: Use autocomplete functionality to complete a input field Given there is conference data in the database When I am on the "home" page When I fill in "search-text" with "PHP" And I wait for the suggestion box to appear Then I should see "PHPNW"

Example

Sunday, 9 October 11

@javascriptScenario: Use autocomplete functionality to complete a input field Given there is conference data in the database When I am on the "home" page When I fill in "search-text" with "PHP" And I wait for the suggestion box to appear Then I should see "PHPNW"

Great Reuse

Sunday, 9 October 11

// In the UIContext class /**

* @Given /^I wait for the suggestion box to appear$/ */ public function iWaitForTheSuggestionBoxToAppear() { $this->getSession()->wait(5000, "$('.suggestions-results').children().length > 0" ); }

Sunday, 9 October 11

Sunday, 9 October 11

Data

Sunday, 9 October 11

SQL Fixture

Sunday, 9 October 11

Phabric

Sunday, 9 October 11

Phabric

Inserting Data From Gherkin Tables

INSERT INTO event `Name`, `Date`, `Venue`, `Desc`VALUE(‘PHPNW’, ‘2011-10-08 09:00’, ‘Ramada Hotel’, ‘Awesome Conf!’)

Scenario: Given The following events exist | Name | Date | Venue | Desc | | PHPNW | 2011-10-08 09:00 | Ramada Hotel | Awesome conf! | | PHPUK | 2012-02-27 09:00 | London Business Center | Quite good conf. |

Sunday, 9 October 11

Phabric

Transforming Table Headings to DB col names

Scenario: Given The following events exist | Name | Date | Venue | Desc | | PHPNW | 2011-10-08 09:00 | Ramada Hotel | Awesome conf! | | PHPUK | 2012-02-27 09:00 | London Business Center | Quite good conf. |

INSERT INTO event `name`, `date`, `venue`, `description`VALUE(‘PHPNW’, ‘2011-10-08 09:00’, ‘Ramada Hotel’, ‘Awesome Conf!’)

Sunday, 9 October 11

Phabric

Transforming Table data using user defined callbacks

Scenario: Given The following events exist | Name | Date | Venue | Desc | | PHPNW | 08/10/2011 09:00 | Ramada Hotel | Awesome conf! | | PHPUK | 27/02/2012 09:00 | London Business Center | Quite good conf. |

INSERT INTO event `name`, `date`, `venue`, `description`VALUE(‘PHPNW’, ‘2011-10-08 09:00’, ‘Ramada Hotel’, ‘Awesome Conf!’)

Sunday, 9 October 11

PhabricInserting Relational Data

Scenario: Given the following sessions exist | Session Code | name | time | description | | BDD | BDD with behat | 12:50 | TDD is cool! | | CI | Continous Integration | 13:30 | Integrate this! | And the following attendees exist | name | | Jack The Lad | | Simple Simon | | Peter Pan | And the following votes exist | Attendee | Session Code | Vote | | Jack The Lad | BDD | UP | | Simple Simon | BDD | UP | | Peter Pan | BDD | UP |

Sunday, 9 October 11

Back To Our Problem At Sky

Sunday, 9 October 11

Balance.

Sunday, 9 October 11

A whole world of trouble.

Sunday, 9 October 11

Questions?

Sunday, 9 October 11

Behat Github Page: https://github.com/Behat/Behat

Mink On Github: https://github.com/Behat/Mink

Website: http://behat.org/

Phabric On Github: https://github.com/benwaine/Phabric

Links

joind.in: http://joind.in/3592 Sunday, 9 October 11