7 + 4 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.

You are here

The BDD library for PHP

What’s BDD? Simple question. BDD is an acronym of: Behavior Driven Development (maybe I prefer to use "Design", instead of "Development"). If we want to speak about BDD, first we need to speak about TDD (Test-Driven Development/Design). Maybe you are familiarized with TDD. TDD is a Software development process. The idea of TDD is simple. When we want to write code, first we write one failing test (Red). Then we write the code to pass this failing test and finally our test passes (Green). After several Red-Green cycles we can Refactor (we only refactor on green). The motto of test-driven development is "Red, Green, Refactor.".

More or less TDD is simple. There’re are several Tools in PHP and probably the most important one is PHPUnit. [1] PHPUnit is the "standard" tool for unit testing in PHP, indeed. But this article is about BDD, What’s the difference between TDD and BDD?. According to two of the most important actors in the Development scenario, Robert C. Martin and Kent Beck (notice that I stand up when I speak about those two people) there isn’t a simple answer. Robert C. Martin (a.k.a. "Uncle Bob", the writer or the new developer Bible "The Clean Code") "BDD is just TDD". By the other hand Kent Beck (one of the founders of the Extreme Programming (XP) and the Agile Manifesto), thinks that TDD is one part of BDD. Without TDD we cannot work with TDD. BDD extends TDD to one higher level

A little mess, isn’t it? In my humble opinion BDD is the same idea but maybe it can be use for a broader audience. It isn’t only focussed on developers. With BDD, managers, and business owner can play an important part within the way of design software.

Too much philosophy, isn’t it? Let’s play with something more concrete and let’s speak about the subject in question: Behat. [2] Behat is Behavior Driven Development framework for PHP applications inspired in a famous Ruby’s tool called Cucumber. [3] The idea of Cucumber (and Behat) is to create human readable sentences to describe our application. Notice the "human readable". That means that everybody can read the features of our application. No matter if the reader is a developer or a business owner. Everybody can read it and contribute. To do that Behat implements a tool called Gherkin. Gherkin provides us a natural language, easy to understand and communicate with the client but it’s also well defined and it’s easily automated with software tools. Do you want an example? A good one can be taken from the Behat’s project page:

Scenario:
  Given I am in a directory "test"
  And I have a file named "foo"
  And I have a file named "bar"
  When I run "ls"
  Then I should get: """ bar foo """

This code is just a specification of a program. As you can see is readable, and with a glance you can figure out how it works. But it isn’t only a simple documentation. It uses Gherkin, and Gherkin can be interpreted by a software (Behat in our case). That’s means that this piece of text "compiles" and we can use it to test our application. It’s an agreement that our program must fulfill. 

With Behat we define "Features". Each feature has its file with the extension ".feature". Features are different points that our program must fulfill. In each feature file we define different Scenarios. The example above is just one scenario from our program. Scenarios have Steps. In our example we have five steps. It’s pretty straightforward. But if you are reading this article, probably you are a developer and developers prefer code than boring text, so let’s create an example from scratch using Behat. In this example we are going to develop String Calculator [4] Coding Kata (at least the first steps). If you are not familiarized with Coding Kata, it is a term borrowed from martial arts. They are simple exercises that help us to improve our skills. The aim of a Kata is not to solve the exercise that is normally very simple. The aim is to grow as a developer solving the exercise again and again, using different approaches and perspectives within each iteration.

Having said that let’s start with our String Calculator. First we prepare our environment. We are going to use composer to perform this task. So let’s include the Behat library in our composer.json file as it is well documented in Behat’s project page:

{

   "require":{

       "behat/behat":"2.4.*@stable"

   },

   "minimum-stability":"dev",

   "config":{

       "bin-dir":"bin/"

   },

   "autoload":{

       "psr-0":{

           "":"lib/"

       }

   }

}

We execute "composer install" and Behat is installed. Now we are going to initialize Behat within our project:

 

./bin/behat --init

+d features - place your *.feature files here

+d features/bootstrap - place bootstrap scripts and static files here

+f features/bootstrap/FeatureContext.php - place your feature related code here

 

This script creates the file structure needed to run Behat. So now we are going to create our first feature in "features/StringCalculator.feature". This feature will have our first scenario. Just the first step of the kata: "Add an empty string returns 0"

Feature: String Calculator

  Scenario: Add an empty string returns 0

    Given StringCalculator instance

    When I Add ""

    Then I expect it to return 0

 

Now we can run Behat to check our application:

 

./bin/behat

Feature: String Calculator

  Scenario: Add an empty string returns zero # features/StringCalculator.feature:3

    Given StringCalculator instance

    When I Add ""

    Then I expect it to return zero

 

1 scenario (1 undefined)

3 steps (3 undefined)

0m0.048s

 

You can implement step definitions for undefined steps with these snippets:

 

    /**

    * @Given /^StringCalculator instance$/

    */

   public function stringcalculatorInstance()

   {

       throw new PendingException();

   }

 

   /**

    * @When /^I Add "([^"]*)"$/

    */

   public function iAdd($arg1)

   {

       throw new PendingException();

   }

 

   /**

    * @Then /^I expect it to return (\d+)$/

    */

   public function iExpectItToReturn($arg1)

   {

       throw new PendingException();

   }

 

Confused? Maybe the first time but if we read the output of the script we will realize that it’s very simple. We have written our first feature file with the specification, but Behat is not a wizard. It won’t write the code for us and it also doesn’t know how to check if our application works according to our feature file. But at least it helps us with the process. We only need to copy the hints that Behat throws us in bootstrap/FeatureContext.php. Now we run again Behat and:

 

./bin/behat

Feature: String Calculator

 

  Scenario: Add an empty string returns zero # features/StringCalculator.feature:3

    Given StringCalculator instance          # FeatureContext::stringcalculatorInstance()

      TODO: write pending definition

    When I Add ""                            # FeatureContext::iAdd()

    Then I expect it to return zero          # FeatureContext::iExpectItToReturnZero()

 

1 scenario (1 pending)

3 steps (2 skipped, 1 pending)

0m0.047s

 

Now is different. Behat tell us something like: "I notice that there’s one scenario with three steps, but it fails." That means that we need to define those steps. Let’s start with the first one. Now we replace the original stringcalculatorInstance function with:

 

    private $stringCalculator;

   /**

    * @Given /^StringCalculator instance$/

    */

   public function stringcalculatorInstance()

   {

       $this->stringCalculator = new StringCalculator();

   }

 

We also need to create the StringCalculator class. We create it in the lib directory.

 

<?php

class StringCalculator{}

 

Now we can run behat again and …

 

./bin/behat

...

1 scenario (1 pending)

3 steps (1 passed, 1 skipped, 1 pending)

0m0.054s

First step is green. Good!. Let’s go with the second one:

    private $textToAdd;

    /**

     * @When /^I Add "([^"]*)"$/

     */

    public function iAdd($text)

    {

        $this->textToAdd = $text;

    }

 

And our behat execution:

 

./bin/behat

...

1 scenario (1 pending)

3 steps (2 passed, 1 pending)

0m0.048s

 

Now we are going to face the most important step within our scenario "Then I expect it to return 0". Behat doesn’t have any assertion library. We can use any library, but it fits perfectly with PHPUnit, so we only need to include PHPUnit in our composer.json file:

 

...

"require":{

        "behat/behat":"2.4.*@stable",

        "phpunit/phpunit": "3.7.13"

    },

...

 

Now if we update our run "composer update" again and uncomment the PHPUnit include in our FeatureContext.php we can use assertions in the same way than we use them with PHPUnit

 

    /**

     * @Then /^I expect it to return (\d+)$/

     */

    public function iExpectItToReturn($expected)

    {

        assertEquals($expected, $this->stringCalculator->add($this->textToAdd));

    }

 

Now our Behat execution fails, (remember: red first), but we can fix it:

 

class StringCalculator

{

    public function add($text)

    {

        return 0;

    }

}

 

Now everything works:

 

./bin/behat

Feature: String Calculator

 

  Scenario: Add an empty string returns zero # features/StringCalculator.feature:3

    Given StringCalculator instance          # FeatureContext::stringcalculatorInstance()

    When I Add ""                            # FeatureContext::iAdd()

    Then I expect it to return 0             # FeatureContext::iExpectItToReturn()

 

1 scenario (1 passed)

3 steps (3 passed)

0m0.056s

 

Our first feature works, let’s go to the second one. Now we are going to check "Add "1" returns 1". So we add another scenario to our feature file:

 

  Scenario: Add "1" returns 1

    Given StringCalculator instance

    When I Add "1"

    Then I expect it to return 1

 

As we can read our steps are the same than the first scenario, because of that if we run Behat again, it will not say "Hey I don’t know how to implement your steps". So we don’t need to change anything within our FeatureContext.php file, we only need to change the implementation of the StringCalculator to meet with the new requirements:

 

<?php

class StringCalculator

{

    public function add($text)

    {

        return $text == '' ? 0 : $text;

    }

}

 

And that’s all. Now our Behat again:

 

./bin/behat

Feature: String Calculator

...

2 scenarios (2 passed)

6 steps (6 passed)

0m0.065s

 

We can keep on with our kata adding new features and implementing the appropriate functionality. Remember: baby steps, first the failing the test, and then the code. As you can see I like to use BDD in the same way than TDD.

 

.

Behavior Driven Development

List mode
Table mode
Icons mode

Displaying 1 - 22 of 22

Title Testing Objectives Since Price Quotes Ping
Cucumber 2,008 2015: Free use, 2015:Paid support plans - Basic: $5000/year (4 requests/month), 2015:Paid support plans - Standard: $7500/year (6 requests/month), 2015:Paid support plans - Enterprise: $20000/year (10 requests/month) Active
Hiptest 2,014 Active
Robot Framework Desktop testing, Java testing, Web testing 2,008 Free to use Active
SpecFlow 2,011 Free to use, 2015: Professional support: Pay/minute: € 35 / 15 minutes, 2015: Professional support: Pay/incident: € 300 / incident Active
FitNesse DataBase testing, Desktop testing, Web testing 2,009 Free Use Active
Squish Desktop testing, Embedded Software, Java testing, Mobile Testing, Web testing, Cross-Browser testing 2,003 April 2015 - Group license : Up-front license fee 7440 €; includes first 12 months of support & updates subscription., April 2015 - Named User License : Up-front license fee 6900 €; includes first 12 months of support & updates subscription. Active
Concordion Web testing 2,006 Free use Active
JBehave Test Design 2,003 Free use Active
Chakram API testing, Web testing 2,014 Free use Active
NBehave 2,007 Free use, BSD License 2014
Codeception API testing, SOA testing, Web testing 2,012 Free Use Active
JWebUnit Web testing 2,012 Free Use Active
PHPUnit Code Analysis, Code Coverage testing, Coding Standards verfication, Static Code Analysis, DataBase testing 2,006 Free use Active
Frank Mobile Testing, Desktop testing 2,011 Free use Active
UISpec Desktop testing, Mobile Testing 2,010 Free Use Active
Freshen Web testing 2,009 Free Use 2015
Behat 2,011 Free Use Active
Jasmine 2,010 Free Use Active
RSpec Test Cases Statistics 2,009 Free Use Active
Testenium Framework Web testing 2,015 Active
MiniTest Code Review 2,012 Free Use Active
Karate SOA testing, Web Services, Payload Validation, Web testing 2,016 Not Published Active

MANUFACTURERS Wallboard

Testing tool manufacturers world-wide list
10Levels ABID CONSULTING AccelQ Accord Software ActiMind AdaCore
AdaLog AgileLoad AgileWay Agitar Algorismi ALL4TEC
Android Apache Apica Apollo Systems AppAssist.mobi Applitools
AppPerfect Appsee ApTest Assertible Assure Atlassian
AutoIt Consulti .. Automation Anyw .. Automation Cons .. Aztaz Software Backtrace I/O Badboy
BlazeMeter Borvid BrowserStack BSQUARE BStriker Intern .. CA Technologies
Canonical Canoo Catch Limited CelestialTeapot Celtic Testing .. Chris Mallett
Cleanscape CloudQA CodeCentrix CodePlex projec .. Codoid Cogitek
Compuware Configure IT Conflair ConSol Core Services Countersoft
CresTech Softwa .. Cross Browser T .. Crosscheck Netw .. Crowdsourced Te .. Cucumber Ltd Cyara
Cygnet Infotech DareBoost Databene Datamatics Glob .. DevExpress DTM soft
Dynatrace LLC EasyQA Eclipse EKA TechServ Elvior Emmanuel Jorge
Empirix EPAM Systems Equafy Esterel eXept Software .. Experitest
Finaris Froglogic FrontEndART Ltd GeneXus GitHub project gnoso
Google Code Pro .. GrammaTech Gurock Software Hewlett Packard .. Hexawise High-Tech Bridg ..
Hiptest Hitex IBM Rational imbus Shanghai Impetus Inflectra
informUp INTALIO intechnica InTENSO - IT Ex .. Ipswitch Jamo Solutions
JANOVA JAR Technologie .. JBoss Developer jClarity Jellly.io JetBrains
Jively jQuery foundati .. JS Foundation Jspresso Kanoah Software KMS Technology
Kualitee LDRA Limited Litmus LoadFocus Loadster Perfor .. MarathonITE
Marketcircle Marketcircle Maveryx Meliora Ltd Micro Focus Sof .. Microsoft
Mobile Labs Mobile1st Mockaroo, LLC ModalLogic IT Monkop Inc Mozila
MSys Technologi .. Navicat NeoTys NetCart Netvantage Tech .. NORIZZK.COM
Novosync Mobili .. NRG Global NTT Resonant OC Systems Odin Technology OpCord
Oracle Orcanos Original Softwa .. Ossia Conseil OW2 PANAYA
Parasoft PassMark Patterson Consu .. Perfecto Mobile Pivotal Labs Plutora
Polarion Postman (API To .. PractiTest PrimaTest Process One Programming Res ..
Psoda PureLoad PushToTest Python Q-Assurance QA Systems
QACube QASymphony QAWorks QMetry Quali QualiTest
Qualitia Softwa .. Quality First S .. Quotium RadView Softwar .. Ranorex RedLine13
Reflective Solu .. ReQtest RevDeBug Robotium Tech Rogue Wave Soft .. Rommana Softwar ..
RTTS ruby-doc.org Runscope Sandklef GNU La .. Sauce Labs Seapine Softwar ..
SeleniumHQ Sencha Sensiple SmartBear Softw .. SmarteSoft SOASTA
SoftLogica Softomotive Softsmith SolutionSoft Sy .. SonarSource Sourceforge
SqashTeam SQS Software Qu .. Square Stimulus Techno .. Swifting AB Synopsys
T-komp T-Plan TechExcel TechTalk Telerik By Prog .. Tellurium
Test Collab Test Goat Test Recon TestCaseLab testCloud.de Gm .. Testenium
Testim.io Testing Technol .. TestingBot TestLodge Testmunk TestObject GmbH
TestOptimal TestPlant TestPro Testuff The Core Bankin .. The MathWorks
The Open Group thePHP.cc Thoughtbot Thoughtworks Tigris.org Time Simulator
Top-Q Trace Technolog .. TrendIC TRICENTIS Tritusa Pty Ltd TWD Solutions P ..
TypeMock Tyto Software Ubertesters UniTESK Universal Test .. Usetrace Ltd
Utrecht Univers .. Validata Group Vanamco AG Vector Software Veracode Verifaya Corpor ..
Verit VersionOne Viewlike.us Vornex Inc. Watir.com WcfStorm Soluti ..
We Are Mammoth Web Performance .. Wikidi Wintask Wireshark Found .. Worksoft
Xceptance XebiaLabs XK72 Xpand IT XQual YesSo
ZAPTEST Zeenyx Software .. Zephyr Zeta Software zutubi pty

Theme by Danetsoft and Danang Probo Sayekti