SlideShare a Scribd company logo
1 of 19
Download to read offline
Test Driven Development
with Behat and Silex
Dionysios Tsoumas
Developer at Zoottle
Our
requirements
- A lightweight framework
- Test driven development
What we went
with
- Silex
- Behat
Silex
A PHP micro-framework based on Symfony components
Behat
Behat
Test driven development
(TDD)
“Test-driven development is a programming technique that
requires you to write actual code and automated test code simultaneously.
This ensures that you test your code—and enables you
to retest your code quickly and easily, since it's automated.”
— Sane programmer who tests his programs
Behaviour driven
development (BDD)
With BDD, you write human-readable stories
that describe the behaviour of your application
That sounds cool!
Behaviour driven
development (BDD)
Step 1 : Write an automated test
Step 2 : Test fail :(
Step 3 : Write code that passes the test
Step 4 : Refactor code
Repeat
Behat
Uses gherkin syntax to make Behaviour driven possible
Feature: Multiple site support
Background:
Given a global administrator named "Greg"
And a blog named "Greg's anti-tax rants"
And a customer named "Wilson"
And a blog named "Expensive Therapy" owned by "Wilson"
Scenario: Wilson posts to his own blog
Given I am logged in as Wilson
When I try to post to "Expensive Therapy"
Then I should see "Your article was published."
Scenario: Greg posts to a client's blog
Given I am logged in as Greg
When I try to post to "Expensive Therapy"
Then I should see "Your article was published."
Step 1: Planning
entities and mapping
controllers and routes
but also
• authentication
• permissions
• response format
Step 2: Functionality to tests
Scenario: Get the campaigns
When I request "GET" "/campaign/" with parameters:
"""
{
"api_key": "1"
}
"""
Then the response status code should be "200"
Then JSON response key "success" should have the boolean value "true"
Then JSON response should contain a key "data"
And that key should have a value of type "array"
And that array should contain an element with the field value of "id" to be "1"
And that array should contain an element with the field value of "name" to be "My existing campaign"
When
run
Scenario: Get the campaigns
When I request "GET" "/campaign/" with parameters:
"""
{
"api_key": "1"
}
"""
Then the response status code should be "200"
Then JSON response key "success" should have the boolean value "true"
Then JSON response should contain a key "data"
And that key should have a value of type "array"
And that array should contain an element with the field value of "id" to be "1"
And that array should contain an element with the field value of "name" to be "My existing campaign"
Scenario: Get the campaigns
When I request "GET" "/campaign/" with parameters:
"""
{
"api_key": "1"
}
"""
Then the response status code should be "200"
Then JSON response key "success" should have the boolean value "true"
Then JSON response should contain a key "data"
And that key should have a value of type "array"
And that array should contain an element with the field value of "id" to be "1"
And that array should contain an element with the field value of "name" to be "My existing campaign”
1 scenario (1 undefined)
7 steps (7 undefined)
Step 3: Gherkin syntax to unit tests
/**
* @When /^I request "([^"]*)" "([^"]*)" with parameters:$/
*/
public function iRequestWithParameters($requestMethod, $pageUrl, PyStringNode $postParametersStringNode)
{
$pageUrl = "http://" . self::$recommendUsApp["url"] . $pageUrl;
$parameters = json_decode($postParametersStringNode->getRaw(), true);
if ($requestMethod === "GET") {
$response = self::$client->get($pageUrl . "?" . http_build_query($parameters));
} else if ($requestMethod === "POST") {
$response = self::$client->post($pageUrl, array("body" => $parameters));
} else if ($requestMethod === "PUT") {
$response = self::$client->put($pageUrl, array("body" => $parameters));
}
$this->response = $response;
}
Example 1
Step 3: Gherkin syntax to unit tests
/**
* @Then /^the response status code should be "([^"]*)"$/
*/
public function responseStatusIs($statusCode)
{
assertEquals($statusCode, $this->response->getStatusCode());
}
Example 2
Step 4 : Write actual code
..finally
The good
- Good for prototyping
- Less things break
- Only way for your project manager to write some code
The bad
- We had to rewrite core asserts
The ugly
- We forgot to test every case
- Too time consuming
- Is it much better than what we currently had?
So how was it?
- Testing with Selenium would be exactly the same
- Possibly better suited for bigger teams

More Related Content

What's hot

Leveraging parse.com for Speedy Development
Leveraging parse.com for Speedy DevelopmentLeveraging parse.com for Speedy Development
Leveraging parse.com for Speedy DevelopmentAndrew Kozlik
 
Django tech-talk
Django tech-talkDjango tech-talk
Django tech-talkdtdannen
 
How to automate all your SEO projects
How to automate all your SEO projectsHow to automate all your SEO projects
How to automate all your SEO projectsVincent Terrasi
 
Web Automation Testing Using Selenium
Web Automation Testing Using SeleniumWeb Automation Testing Using Selenium
Web Automation Testing Using SeleniumPete Chen
 
Simplifying Code: Monster to Elegant in 5 Steps
Simplifying Code: Monster to Elegant in 5 StepsSimplifying Code: Monster to Elegant in 5 Steps
Simplifying Code: Monster to Elegant in 5 Stepstutec
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
Poisoning Google images
Poisoning Google imagesPoisoning Google images
Poisoning Google imageslukash4
 
Integrating External APIs with WordPress
Integrating External APIs with WordPressIntegrating External APIs with WordPress
Integrating External APIs with WordPressMarty Thornley
 
Learn How To Use CA PPM REST API in 2 minutes!
Learn How To Use CA PPM REST API in 2 minutes!Learn How To Use CA PPM REST API in 2 minutes!
Learn How To Use CA PPM REST API in 2 minutes!Prominder Nayar
 
Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Engine Yard
 
You're Doing It Wrong
You're Doing It WrongYou're Doing It Wrong
You're Doing It Wrongbostonrb
 
Best ways to use the ShareASale API
Best ways to use the ShareASale APIBest ways to use the ShareASale API
Best ways to use the ShareASale APIericnagel
 
Hidden Treasures in Project Wonder
Hidden Treasures in Project WonderHidden Treasures in Project Wonder
Hidden Treasures in Project WonderWO Community
 

What's hot (16)

Leveraging parse.com for Speedy Development
Leveraging parse.com for Speedy DevelopmentLeveraging parse.com for Speedy Development
Leveraging parse.com for Speedy Development
 
Django tech-talk
Django tech-talkDjango tech-talk
Django tech-talk
 
How to automate all your SEO projects
How to automate all your SEO projectsHow to automate all your SEO projects
How to automate all your SEO projects
 
Agile and rails
Agile and railsAgile and rails
Agile and rails
 
Jsp
JspJsp
Jsp
 
Presentation
PresentationPresentation
Presentation
 
Web Automation Testing Using Selenium
Web Automation Testing Using SeleniumWeb Automation Testing Using Selenium
Web Automation Testing Using Selenium
 
Simplifying Code: Monster to Elegant in 5 Steps
Simplifying Code: Monster to Elegant in 5 StepsSimplifying Code: Monster to Elegant in 5 Steps
Simplifying Code: Monster to Elegant in 5 Steps
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Poisoning Google images
Poisoning Google imagesPoisoning Google images
Poisoning Google images
 
Integrating External APIs with WordPress
Integrating External APIs with WordPressIntegrating External APIs with WordPress
Integrating External APIs with WordPress
 
Learn How To Use CA PPM REST API in 2 minutes!
Learn How To Use CA PPM REST API in 2 minutes!Learn How To Use CA PPM REST API in 2 minutes!
Learn How To Use CA PPM REST API in 2 minutes!
 
Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel
 
You're Doing It Wrong
You're Doing It WrongYou're Doing It Wrong
You're Doing It Wrong
 
Best ways to use the ShareASale API
Best ways to use the ShareASale APIBest ways to use the ShareASale API
Best ways to use the ShareASale API
 
Hidden Treasures in Project Wonder
Hidden Treasures in Project WonderHidden Treasures in Project Wonder
Hidden Treasures in Project Wonder
 

Viewers also liked (10)

Lápiz en mano
Lápiz en manoLápiz en mano
Lápiz en mano
 
peerj-2133
peerj-2133peerj-2133
peerj-2133
 
Forbes-interview - May 2015
Forbes-interview - May 2015Forbes-interview - May 2015
Forbes-interview - May 2015
 
TIPOS DE CARTAS
TIPOS DE CARTASTIPOS DE CARTAS
TIPOS DE CARTAS
 
Profit plus
Profit plusProfit plus
Profit plus
 
Tipos de cartas
Tipos de cartasTipos de cartas
Tipos de cartas
 
Apple Certified ACSP 10.6.PDF
Apple Certified ACSP 10.6.PDFApple Certified ACSP 10.6.PDF
Apple Certified ACSP 10.6.PDF
 
Williander chavez
Williander chavezWilliander chavez
Williander chavez
 
Briefing Exemplo Janaira França
Briefing Exemplo Janaira FrançaBriefing Exemplo Janaira França
Briefing Exemplo Janaira França
 
Planejamento dolly
Planejamento dollyPlanejamento dolly
Planejamento dolly
 

Similar to behat

jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)Doris Chen
 
Open Social In The Enterprise
Open Social In The EnterpriseOpen Social In The Enterprise
Open Social In The EnterpriseTim Moore
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)David Giard
 
Merrill's Journey to CI-CD and Continuous Testing by Ashish Mukherjee
Merrill's Journey to CI-CD and Continuous Testing by Ashish MukherjeeMerrill's Journey to CI-CD and Continuous Testing by Ashish Mukherjee
Merrill's Journey to CI-CD and Continuous Testing by Ashish MukherjeeSauce Labs
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
After max+phonegap
After max+phonegapAfter max+phonegap
After max+phonegapyangdj
 
混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaveryangdj
 
Taking Web Apps Offline
Taking Web Apps OfflineTaking Web Apps Offline
Taking Web Apps OfflinePedro Morais
 
API first with Swagger and Scala by Slava Schmidt
API first with Swagger and Scala by  Slava SchmidtAPI first with Swagger and Scala by  Slava Schmidt
API first with Swagger and Scala by Slava SchmidtJavaDayUA
 
Behaviour driven infrastructure
Behaviour driven infrastructureBehaviour driven infrastructure
Behaviour driven infrastructureLindsay Holmwood
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineYared Ayalew
 
Educate 2017: Customizing Assessments: Why extending the APIs is easier than ...
Educate 2017: Customizing Assessments: Why extending the APIs is easier than ...Educate 2017: Customizing Assessments: Why extending the APIs is easier than ...
Educate 2017: Customizing Assessments: Why extending the APIs is easier than ...Learnosity
 
Prairie DevCon 2015 - Crafting Evolvable API Responses
Prairie DevCon 2015 - Crafting Evolvable API ResponsesPrairie DevCon 2015 - Crafting Evolvable API Responses
Prairie DevCon 2015 - Crafting Evolvable API Responsesdarrelmiller71
 
Mongo and Harmony
Mongo and HarmonyMongo and Harmony
Mongo and HarmonySteve Smith
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceParashuram N
 

Similar to behat (20)

jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
 
Gaej For Beginners
Gaej For BeginnersGaej For Beginners
Gaej For Beginners
 
Open Social In The Enterprise
Open Social In The EnterpriseOpen Social In The Enterprise
Open Social In The Enterprise
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)How I Learned to Stop Worrying and Love jQuery (Jan 2013)
How I Learned to Stop Worrying and Love jQuery (Jan 2013)
 
Merrill's Journey to CI-CD and Continuous Testing by Ashish Mukherjee
Merrill's Journey to CI-CD and Continuous Testing by Ashish MukherjeeMerrill's Journey to CI-CD and Continuous Testing by Ashish Mukherjee
Merrill's Journey to CI-CD and Continuous Testing by Ashish Mukherjee
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
bcgr3-jquery
bcgr3-jquerybcgr3-jquery
bcgr3-jquery
 
bcgr3-jquery
bcgr3-jquerybcgr3-jquery
bcgr3-jquery
 
After max+phonegap
After max+phonegapAfter max+phonegap
After max+phonegap
 
混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver
 
Taking Web Apps Offline
Taking Web Apps OfflineTaking Web Apps Offline
Taking Web Apps Offline
 
Real World MVC
Real World MVCReal World MVC
Real World MVC
 
API first with Swagger and Scala by Slava Schmidt
API first with Swagger and Scala by  Slava SchmidtAPI first with Swagger and Scala by  Slava Schmidt
API first with Swagger and Scala by Slava Schmidt
 
Behaviour driven infrastructure
Behaviour driven infrastructureBehaviour driven infrastructure
Behaviour driven infrastructure
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App Engine
 
Educate 2017: Customizing Assessments: Why extending the APIs is easier than ...
Educate 2017: Customizing Assessments: Why extending the APIs is easier than ...Educate 2017: Customizing Assessments: Why extending the APIs is easier than ...
Educate 2017: Customizing Assessments: Why extending the APIs is easier than ...
 
Prairie DevCon 2015 - Crafting Evolvable API Responses
Prairie DevCon 2015 - Crafting Evolvable API ResponsesPrairie DevCon 2015 - Crafting Evolvable API Responses
Prairie DevCon 2015 - Crafting Evolvable API Responses
 
Mongo and Harmony
Mongo and HarmonyMongo and Harmony
Mongo and Harmony
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
 

behat

  • 1. Test Driven Development with Behat and Silex Dionysios Tsoumas Developer at Zoottle
  • 2. Our requirements - A lightweight framework - Test driven development What we went with - Silex - Behat
  • 3. Silex A PHP micro-framework based on Symfony components
  • 6. Test driven development (TDD) “Test-driven development is a programming technique that requires you to write actual code and automated test code simultaneously. This ensures that you test your code—and enables you to retest your code quickly and easily, since it's automated.” — Sane programmer who tests his programs
  • 7. Behaviour driven development (BDD) With BDD, you write human-readable stories that describe the behaviour of your application That sounds cool!
  • 8. Behaviour driven development (BDD) Step 1 : Write an automated test Step 2 : Test fail :( Step 3 : Write code that passes the test Step 4 : Refactor code Repeat
  • 9. Behat Uses gherkin syntax to make Behaviour driven possible Feature: Multiple site support Background: Given a global administrator named "Greg" And a blog named "Greg's anti-tax rants" And a customer named "Wilson" And a blog named "Expensive Therapy" owned by "Wilson" Scenario: Wilson posts to his own blog Given I am logged in as Wilson When I try to post to "Expensive Therapy" Then I should see "Your article was published." Scenario: Greg posts to a client's blog Given I am logged in as Greg When I try to post to "Expensive Therapy" Then I should see "Your article was published."
  • 10. Step 1: Planning entities and mapping controllers and routes but also • authentication • permissions • response format
  • 11. Step 2: Functionality to tests Scenario: Get the campaigns When I request "GET" "/campaign/" with parameters: """ { "api_key": "1" } """ Then the response status code should be "200" Then JSON response key "success" should have the boolean value "true" Then JSON response should contain a key "data" And that key should have a value of type "array" And that array should contain an element with the field value of "id" to be "1" And that array should contain an element with the field value of "name" to be "My existing campaign"
  • 12. When run Scenario: Get the campaigns When I request "GET" "/campaign/" with parameters: """ { "api_key": "1" } """ Then the response status code should be "200" Then JSON response key "success" should have the boolean value "true" Then JSON response should contain a key "data" And that key should have a value of type "array" And that array should contain an element with the field value of "id" to be "1" And that array should contain an element with the field value of "name" to be "My existing campaign" Scenario: Get the campaigns When I request "GET" "/campaign/" with parameters: """ { "api_key": "1" } """ Then the response status code should be "200" Then JSON response key "success" should have the boolean value "true" Then JSON response should contain a key "data" And that key should have a value of type "array" And that array should contain an element with the field value of "id" to be "1" And that array should contain an element with the field value of "name" to be "My existing campaign” 1 scenario (1 undefined) 7 steps (7 undefined)
  • 13. Step 3: Gherkin syntax to unit tests /** * @When /^I request "([^"]*)" "([^"]*)" with parameters:$/ */ public function iRequestWithParameters($requestMethod, $pageUrl, PyStringNode $postParametersStringNode) { $pageUrl = "http://" . self::$recommendUsApp["url"] . $pageUrl; $parameters = json_decode($postParametersStringNode->getRaw(), true); if ($requestMethod === "GET") { $response = self::$client->get($pageUrl . "?" . http_build_query($parameters)); } else if ($requestMethod === "POST") { $response = self::$client->post($pageUrl, array("body" => $parameters)); } else if ($requestMethod === "PUT") { $response = self::$client->put($pageUrl, array("body" => $parameters)); } $this->response = $response; } Example 1
  • 14. Step 3: Gherkin syntax to unit tests /** * @Then /^the response status code should be "([^"]*)"$/ */ public function responseStatusIs($statusCode) { assertEquals($statusCode, $this->response->getStatusCode()); } Example 2
  • 15. Step 4 : Write actual code ..finally
  • 16. The good - Good for prototyping - Less things break - Only way for your project manager to write some code
  • 17. The bad - We had to rewrite core asserts
  • 18. The ugly - We forgot to test every case - Too time consuming - Is it much better than what we currently had?
  • 19. So how was it? - Testing with Selenium would be exactly the same - Possibly better suited for bigger teams