bdd - you're doing it all wrong!

35
Andrew Larcombe @andrewl BDD? You’re doing it all wrong! (perhaps)

Upload: andrew-larcombe

Post on 16-Jul-2015

231 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: BDD - you're doing it all wrong!

Andrew Larcombe @andrewl

BDD? You’re doing it all wrong!

(perhaps)

Page 2: BDD - you're doing it all wrong!

Who am I?!Software Delivery Professional"Engineering: Drupal (nodejs, go-lang, solr, geospatial, ruby-on-rails, perl, c++)Process: Agile, Scrum, BDD"t: @andrewl w: andrewl.nete: [email protected]"

"

fluxus.io

Page 3: BDD - you're doing it all wrong!

"

"

What is Behavioural Driven Development?

Some common anti-patterns

Page 4: BDD - you're doing it all wrong!
Page 5: BDD - you're doing it all wrong!

“BDD is a second-generation, outside–in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology.”

(Dan North)

Page 6: BDD - you're doing it all wrong!
Page 7: BDD - you're doing it all wrong!

The Problem!We have complex communication problems, not technical problems (mostly)."Jargon, ‘Chinese Whispers’, early solutionising"Consequences: Locked in to delivering late, delayed or the wrong product, before we’ve even written a line of code.

Page 8: BDD - you're doing it all wrong!
Page 9: BDD - you're doing it all wrong!

“If I asked my customers what they wanted they would have said ‘a faster

horse’” (Henry Ford)

Page 10: BDD - you're doing it all wrong!

Behat

Page 11: BDD - you're doing it all wrong!

Requirement

Conversation

Discovery

Specification

Automation

For all, in a common language

Behat

Page 12: BDD - you're doing it all wrong!

BDD leads to Executable Specifications with Examples for features that deliver business value and that are written in

the domain language of the business!"

Behat is a tool for automating these specifications.!

Page 13: BDD - you're doing it all wrong!

Some BDD & Behat Antipatterns

Page 14: BDD - you're doing it all wrong!

"

All journeys sold between Brussels and Chicago with a child ticket should have at least one accompanying adult or senior

ticket.

Page 15: BDD - you're doing it all wrong!

As a user

I want to be prevented from purchasing a child only journey from Brussels to Chicago

So that…errr…???

Antipattern #1:“As a User”!

Page 16: BDD - you're doing it all wrong!

As the Company Lawyer

I want to prevent customers purchasing a child only ticket on flights from Brussels to Chicago

So that we’re compliant with regulations

This is the person that cares

This is why they care

Page 17: BDD - you're doing it all wrong!

Given I go to ‘/tickets.php’ And I select ‘0’ from ‘xpath://ticket-form/adults’And I select ‘2’ from ‘xpath://ticket-form/children’And I select ‘0’ from ‘xpath://ticket-form/youths’And I select ‘0’ from ‘xpath://ticket-form/seniors’And I click ‘xpath://ticket-form/submit’Then I should see “You cannot purchase child-only tickets for this journey” And I should be on ‘/tickets.php’

Antipattern #2:“Writing Brittle Tests not Specifications”!

Page 18: BDD - you're doing it all wrong!

Tight coupling with DOM

Tight coupling with URLsHard-coded messages?!?!!

Given I go to ‘/tickets.php’ And I select ‘0’ from ‘xpath://ticket-form/adults’And I select ‘2’ from ‘xpath://ticket-form/children’And I select ‘0’ from ‘xpath://ticket-form/youths’And I select ‘0’ from ‘xpath://ticket-form/seniors’And I click ‘xpath://ticket-form/submit’Then I should see “You cannot purchase child-only tickets for this journey” And I should be on ‘/tickets.php’

Repetition

Who even understands this??!?!!

Antipattern #2:“Writing Brittle Tests not Specifications”!

Page 19: BDD - you're doing it all wrong!

Given I am on the ticket search page When search for tickets from “<origin>” to “<destination>” for “<num_adults”> adults, “<num_children>” children and “<num_seniors> seniors Then I should see the child fare policy messageAnd be on the ticket search page

Examples: |origin |destination|num_adults|num_children|num_seniors||Brussels|Chicago |0 |1 |0 ||Brussels|Chicago |0 |2 |0 ||Brussels|Chicago |0 |3 |0 ||Brussels|Chicago |0 |4 |0 ||Brussels|Chicago |0 |5 |0 |

Page 20: BDD - you're doing it all wrong!

Page Objects!Separation of Concerns"Encapsulation"DRY (Don’t Repeat Yourself)"Hides implementation details"An API for the things you do on a page"e.g. class TicketSearchPage: it’s where you search for tickets (that’s what you do on the ticket search page)

Page 21: BDD - you're doing it all wrong!

§

class SearchPage

function search($origin, $dest, …) { $this->get(‘Search Form’) ->setOrigin($origin);

function warningMessage() { return $this->get

class SearchForm { function setOrigin($origin) { $this ->fillField(“From”, $origin); …etc…

class SearchContext { function iShouldSeePolicyMessage() { expect($this->getPage(‘search’)->warningMessage())->toBe(‘You cannot purchase child-only tickets for this journey’)

…Page Object Contexts

Hide the Complexity - Feature Contexts…

Page 22: BDD - you're doing it all wrong!

Page Objects…an approach!Start with wireframe/ui.""

Describe in English what you do on the page.""

Write a function in your Page object that maps onto a ‘real world’ action that you might perform on the page"eg search(), register(), uploadAnImage(), addAComment().""

Write a function in your Context that maps requirements into these actions and throws exceptions where required.""

Refactor, refactor, refactor

Page 23: BDD - you're doing it all wrong!

"

All journeys sold between Brussels and Capetown with 2 or more child tickets should

have at least one accompanying adult or senior ticket.

Page 24: BDD - you're doing it all wrong!

Given I am on the ticket search page When search for tickets from “<origin>” to “<destination>” for “<num_adults”> adults, “<num_children>” children and “<num_seniors> seniors Then I should see the child fare policy messageAnd be on the ticket search page

Examples: |origin |destination|num_adults|num_children|num_seniors||Brussels|Chicago |0 |1 |0 ||Brussels|Chicago |0 |2 |0 ||Brussels|Chicago |0 |3 |0 ||Brussels|Chicago |0 |4 |0 ||Brussels|Chicago |0 |5 |0 ||Brussels|Capetown |0 |2 |0 ||Brussels|Capetown |0 |3 |0 ||Brussels|Capetown |0 |4 |0 ||Brussels|Capetown |0 |5 |0 |

Page 25: BDD - you're doing it all wrong!

"

Add some front-end validation…after the user selects the origin and destination,

load the rules determining child ticket policies using AJAX

Page 26: BDD - you're doing it all wrong!

Given I go to ‘/tickets.php’ And I select ‘Brussels’ from ‘xpath://ticket-form/origin’ And I select ‘Chicago’ from ‘xpath://ticket-form/destination’ And I wait 3 seconds

Page 27: BDD - you're doing it all wrong!

Given I go to ‘/tickets.php’ And I select ‘Brussels’ from ‘xpath://ticket-form/origin’ And I select ‘Chicago’ from ‘xpath://ticket-form/destination’ And I wait 5 seconds

Never part of anyone’s specification, ever!

Antipattern #3:“And I wait…”!

Page 28: BDD - you're doing it all wrong!

public function spin ($lambda) { while (true) { try { if ($lambda($this)) { return true; } } catch (Exception $e) { //and do nothing here }

sleep(1); //wait and try again in a second } }

$this->spin(function($context) { $context->getSession()->getPage()->findById('adults'); });

"

Spin functions!

Page 29: BDD - you're doing it all wrong!

In review…not writing tests, discovering the specification

Page 30: BDD - you're doing it all wrong!

As a user

I want to be prevented from purchasing a child only journey from Brussels to Chicago

So that…errr…???

Page 31: BDD - you're doing it all wrong!

As the Company Lawyer

I want to prevent customers purchasing a child only ticket on flights from Brussels to Chicago

So that we’re compliant with regulations

Page 32: BDD - you're doing it all wrong!

Given I go to ‘/tickets.php’ And I select ‘0’ from ‘xpath://ticket-form/adults’And I select ‘2’ from ‘xpath://ticket-form/children’And I select ‘0’ from ‘xpath://ticket-form/youths’And I select ‘0’ from ‘xpath://ticket-form/seniors’And I click ‘xpath://ticket-form/submit’Then I should see “You cannot purchase child-only tickets for this journey” And I should be on ‘/tickets.php’

Page 33: BDD - you're doing it all wrong!

Given I am on the ticket search page When search for tickets from “<origin>” to “<destination>” for “<num_adults”> adults, “<num_children>” and “<num_seniors> seniors Then I should see the child fare policy messageAnd be on the ticket search page

Examples: |origin |destination|num_adults|num_children|num_seniors||Brussels|Chicago |0 |1 |0 ||Brussels|Chicago |0 |2 |0 ||Brussels|Chicago |0 |3 |0 ||Brussels|Chicago |0 |4 |0 ||Brussels|Chicago |0 |5 |0 ||Brussels|Capetown |0 |2 |0 ||Brussels|Capetown |0 |3 |0 ||Brussels|Capetown |0 |4 |0 ||Brussels|Capetown |0 |5 |0 |

Page 34: BDD - you're doing it all wrong!

Requirement

Conversation

Discovery

Specification

Automation

For all, in a common language

Behat

Page 35: BDD - you're doing it all wrong!

Links!Reading dannorth.net/introducing-bdddannorth.net/2010/08/30/introducing-deliberate-discoveryspecificationbyexample.com/key_ideas.html “Domain Driven Design” Eric Evans (domainlanguage.com) lizkeogh.com/2010/02/02/theyre-not-user-stories

Playingbehat.orgdrupal.org/project/drupalextensioncode.google.com/p/selenium/wiki/PageObjectsgithub.com/orangedigital/business-selector-extensiongithub.com/BossaConsulting/phpspec2-expect