Behavior-Driven Development on the JVM          A State of the Union                              John	  Ferguson	  Smart
Consulta                    nt            Trainer           Mentor           Author          Speaker          CoderJohn Fe...
What is BDD?
Business Analyst           Common           LanguageBusiness                      Developer              Tester
ExecutableSpecifications
Ou  ts    id       e           In
Value Driven
So why use BDD?Only build features that add real valueLess wasted effortBetter communicationHigher quality, better tested p...
BDD - Requirements Analysis and        Communication
Goals   Capabilities     Features      StoriesExamples/ScenariosAcceptance Criteria
11 Successful projects start with a shared vision“We are going to build an online classifieds website”
12You define goals to achieve your vision                              “We can increase                              advert...
Determining the value of a goal   A good goal should add value to the business    Increase revenue    Reduce costs    Avoi...
What does the customer really need?       I want users to be able to search for products by keywordWhy?        So that pot...
What does the customer really need?  Good teams push back!   Users tend to express requirements as implementations   We ne...
Features and capabilities help deliver these goals             “Let’s get more sales for our advertisers by             ma...
Feature Injection - what features do you do first?  Our goals say what business value we need to deliver  We implement the...
18We use examples and stories to explore the featuresSearch for online ads“Searching by category”   “Searching by keyword ...
19We use examples and stories to explore the featuresSearch for online ads Searching by keyword and location Given	  Sally...
20Examples and scenarios become acceptance criteriaSearching by keyword and location Given	  Sally	  wants	  to	  buy	  a	...
Organize your requirements
Requirements can come from many sources...
Goal:In order to increase revenue from commissions on classified ads salesAs the head of the classified ads departmentI wa...
Requirements can come from many sources...
25BDD - Test Automation and Beyond
26The original Java BDD framework
27search_by_keyword_and_location.story Narrative: In order to increase sales of advertised articles As a seller I want buy...
28search_by_keyword_and_location.story Scenario: Searching by keyword and location Given Sally wants to buy a puppy for he...
29search_by_keyword_and_location.story Scenario: Searching by keyword and location                     1 Given Sally wants...
30search_by_keyword_and_location.story Scenario: Searching by keyword and location                                       1...
31search_by_keyword_and_location.story Scenario: Searching by keyword and location                                        ...
32search_by_keyword_and_location.story Scenario: Searching by keyword and location                                       1...
33Now available in JVM flavor!
34Feature:                                                             1In order to increase sales of advertised articlesA...
35Scenario: Searching by keyword and locationGiven Sally wants to buy a "puppy" for her sonWhen she looks for "puppy" in t...
36Scenario: Searching by keyword and location                     1Given Sally wants to buy a "puppy" for her sonWhen she ...
37Scenario: Searching by keyword and location                                         1Given Sally wants to buy a "puppy" ...
38100% Groovy
39search_by_keyword_and_location.story scenario "Searching by keyword and location", {     given "Sally wants to buy a pup...
40search_by_keyword_and_location.story scenario "Searching by keyword and location", {                       1     given "...
41search_by_keyword_and_location.story scenario "Searching by keyword and location", {                       1     given "...
42Keeping an eye on things
43(Think “Two-CDs”)
44Scenario: Searching by keywordGiven Sally wants to buy a puppy for her sonWhen she looks for ads in the Pets & Animals c...
45Scenario: Searching by keywordGiven Sally wants to buy a puppy for her sonWhen she looks for ads in the Pets & Animals c...
46public class SearchAdsSteps {    @Steps    BuyerSteps buyer;    @Given("Sally wants to buy a $present for her son")    p...
47
48
49
50
51
52
From Acceptance Tests  to Developer Tests
BDD - A Development Tool
TDD or BDD?
Make it passWrite a failing test           TDD                                                   Refactor                 ...
Acceptance Tests       (high level features)                                                        Spock                 ...
Goal: In order to increase revenue from commissions on classified ads salesAs the head of the classified ads departmentI w...
Unit Tests   Acceptance tests
Spock - BDD for developers
Spockclass WhenCalculatingGST extends Specification {    def "GST should apply on ordinary articles"() {        given: "we...
Spockclass WhenCalculatingGST extends Specification {    ...    def "GST should not apply on GST-exempt articles"() {     ...
Spock                          Lightweight stubbingclass WhenCalculatingGST extends Specification {    def "GST should app...
Spockclass WhenDeliveringSoldItems extends Specification {    def gstRateProvider = Mock(GSTRateProvider)    def deliveryS...
Spockclass WhenDisplayingTagNamesInAReadableForm extends Specification {    def inflection = Inflector.instance    def "sh...
Spec2 - BDD for Scala
class	  WhenCalculatingGST	  extends	  Specification	  {	  sequential	  	  "GST	  should	  apply	  on	  ordinary	  article...
class	  WhenCalculatingGST2	  extends	  Specification	  with	  Mockito	  {	  sequential	  	  "GST	  should	  apply	  on	  ...
class	  WhenDeliveringSoldItems	  extends	  Specification	  with	  Mockito	  {	  sequential	  	  "Sold	  articles	  should...
class	  WhenDisplayingTagNamesInAReadableForm	  extends	  Specification	  with	  Tables	  {	  	  "The	  inflector	  should...
Jasmine - BDD for Javascript
describe( "temperature converter", function () {    it("converts fahrenheit to celsius", function () {        expect(Conve...
describe( "temperature converter", function () {    it("converts fahrenheit to celsius", function () {        expect(Conve...
describe( "converter library", function () {    describe( "temperature converter", function () {        it("converts fahre...
And it works with Maven!
Evaluate test results in a browser
Evaluate test results in a browser
Generate JUnit-compatible results
hAp://try-­‐jasmine.heroku.com/
In conclusion...It’s behavior allthe way down
Thank You            John	  Ferguson	  Smart
Upcoming SlideShare
Loading in …5
×

Bdd state-of-the-union

2,762 views

Published on

Behavior-driven development (BDD) is an increasingly popular variation on test-driven development, which helps developers think more in terms of “executable specifications” than in terms of conventional tests. There are dozens of BDD tools for the JVM out there—how do you know what to use and when? This presentation covers the various BDD tools available for Java developers, in both Java and other JVM languages. It looks at the pros and cons of each tool, so you can learn which might be best suited for your team. Finally, you will discover the relationship between behavior-driven development and automated acceptance testing and why you probably need both.

Bdd state-of-the-union

  1. 1. Behavior-Driven Development on the JVM A State of the Union John  Ferguson  Smart
  2. 2. Consulta nt Trainer Mentor Author Speaker CoderJohn Fer guson S mar t
  3. 3. What is BDD?
  4. 4. Business Analyst Common LanguageBusiness Developer Tester
  5. 5. ExecutableSpecifications
  6. 6. Ou ts id e In
  7. 7. Value Driven
  8. 8. So why use BDD?Only build features that add real valueLess wasted effortBetter communicationHigher quality, better tested productTraceability
  9. 9. BDD - Requirements Analysis and Communication
  10. 10. Goals Capabilities Features StoriesExamples/ScenariosAcceptance Criteria
  11. 11. 11 Successful projects start with a shared vision“We are going to build an online classifieds website”
  12. 12. 12You define goals to achieve your vision “We can increase advertising revenue by letting sellers post their classified ads online” “Let’s get more sales for our advertisers by making the ads easier to find online.”
  13. 13. Determining the value of a goal A good goal should add value to the business Increase revenue Reduce costs Avoid future costs Protect revenue “Increase advertising revenue by allowing sellers to post classified ads online” “Reduce the costs involved in publishing a classified ad by allowing sellers to post them online themselves. ” “Prevent current customers switching to a competing product by providing support for online credit card payments”
  14. 14. What does the customer really need? I want users to be able to search for products by keywordWhy? So that potential buyers can find the articles they want Why? So that our sellers can sell their stuff faster Why? So that they keep selling their stuff on our site Why?So that we keep earning money when they post their ads with us
  15. 15. What does the customer really need? Good teams push back! Users tend to express requirements as implementations We need to find the business need behind the suggested implementation I want users to be able to search by keyword So in order to make the site more attractive for sellers Buyers need to be able to find things easily A search feature might be one way to achieve this But full-text searches might be more effective than keywords
  16. 16. Features and capabilities help deliver these goals “Let’s get more sales for our advertisers by making the ads easier to find online.” Notify potential buyers about new items In Search for online of advertised articles order to increase sales ads As aorder to increase sales of advertised articles In seller I want previous buyers to know about new items As a seller that theybuyers be interested in buying ads for I want might to be able to easily find articles they want to buy
  17. 17. Feature Injection - what features do you do first? Our goals say what business value we need to deliver We implement the minimum features required to deliver this business value Search for online ads The goal comes first In order to increase sales of advertised articles The stakeholder is As a seller secondary I want buyers to be able to easily find ads for articles they want to buy The feature must be required to achieve the goal
  18. 18. 18We use examples and stories to explore the featuresSearch for online ads“Searching by category” “Searching by keyword and category”
  19. 19. 19We use examples and stories to explore the featuresSearch for online ads Searching by keyword and location Given  Sally  wants  to  buy  a  puppy  for  her  son   When  she  looks  for  ‘puppy’  in  the  ‘Pets  and  Animals’  category Then  she  should  obtain  a  list  of  ads  for  puppies  for  sale.
  20. 20. 20Examples and scenarios become acceptance criteriaSearching by keyword and location Given  Sally  wants  to  buy  a  puppy  for  her  son   When  she  looks  for  ‘puppy’  in  the  ‘Pets  and  Animals’  category Then  she  should  obtain  a  list  of  ads  for  puppies  for  sale. Scenario: Searching by keyword and location Given Sally wants to buy a present for her son When she looks for the present in a given category Then she should obtain a list of matching ads for sale. Examples: Present Category Expected Keywords puppy Pets & Animals labrador kitten Pets & Animals burmese kitten Toys fluffy cat Acceptance Criteria illustrate and validate the stories
  21. 21. Organize your requirements
  22. 22. Requirements can come from many sources...
  23. 23. Goal:In order to increase revenue from commissions on classified ads salesAs the head of the classified ads departmentI want to increase the number of items sold via our classified ads Capability In order to increase the number of items I sell Feature As a seller In order to increase sales of advertised articles I want buyers to be able to view ads for items As a seller they might want to purchase I want potential buyers to be able to display only the ads for articles that they might be interested in purchasing. Story In order to find the items I am interested in faster Keep them organized! As a buyer I want to be able to list all the ads with a particular keyword in the description or title.
  24. 24. Requirements can come from many sources...
  25. 25. 25BDD - Test Automation and Beyond
  26. 26. 26The original Java BDD framework
  27. 27. 27search_by_keyword_and_location.story Narrative: In order to increase sales of advertised articles As a seller I want buyers to be able to easily find ads for articles they want to buy Scenario: Searching by keyword and location Given Sally wants to buy a puppy for her son When she looks for puppy in the Pets and Animals category Then she should obtain a list of ads for puppies for sale.
  28. 28. 28search_by_keyword_and_location.story Scenario: Searching by keyword and location Given Sally wants to buy a puppy for her son When she looks for puppy in the Pets and Animals category Then she should obtain a list of ads for puppies for sale. Scenario: Searching by keyword and location Given Sally wants to buy a <present> for her son When she looks for <present> in the <category> category Then she should obtain a list of ads for <expected> for sale. Examples: |present |category |expected| |puppy |Pets & Animals | puppies| |kitten |Pets & Animals | kittens| |seiko |Jewellery & Watches| watch |
  29. 29. 29search_by_keyword_and_location.story Scenario: Searching by keyword and location 1 Given Sally wants to buy a puppy for her son When she looks for puppy in the Pets and Animals category Then she should obtain a list of ads for puppies for sale.
  30. 30. 30search_by_keyword_and_location.story Scenario: Searching by keyword and location 1 Given Sally wants to buy a puppy for her son When she looks for puppy in the Pets and Animals category Then she should obtain a list of puppy ads public class SearchAdsSteps {     @Steps 2     BuyerSteps buyer;     @Given("Sally wants to buy a $present for her son")     public void buyingAPresent(String present) {         buyer.opens_home_page();     }     @When("she looks for $keyword in the $category category")     public void adSearchByCategoryAndKeyword(String category, String keyword) {         buyer.chooses_category_and_keywords(category, keyword);         buyer.performs_search();     }     @Then("she should obtain a list of $keyword ads")     public void shouldOnlySeeAdsContainingKeyword(String keyword) {         buyer.should_only_see_results_with_titles_containing(keyword);     } }
  31. 31. 31search_by_keyword_and_location.story Scenario: Searching by keyword and location 1 Given Sally wants to buy a puppy for her son When she looks for puppy in the Pets and Animals category Then she should obtain a list of puppy ads public class SearchAdsSteps {     @Steps 2     BuyerSteps buyer; public class BuyerStories extends JUnitStories {     @Given("Sally wants to buy a $present for her son")     public BuyerStories() {     public void buyingAPresent(String present) { 3         configuredEmbedder().embedderControls().doGenerateViewAfterStories(true).doIgnoreFailureInStories(false)         buyer.opens_home_page();                 .doIgnoreFailureInView(true).doVerboseFailures(true).useThreads(2).useStoryTimeoutInSecs(60);     }     }     @Override     @When("she looks for $keyword { the $category category")     public Configuration configuration() in     public void adSearchByCategoryAndKeyword(String category, String keyword) {         return new MostUsefulConfiguration();     }         buyer.chooses_category_and_keywords(category, keyword);         buyer.performs_search();     @Override     }     public InjectableStepsFactory stepsFactory() {         return new InstanceStepsFactory(configuration(), new TraderSteps(new TradingService()), new AndSteps());     }     @Then("she should obtain a list of $keyword ads")     public void shouldOnlySeeAdsContainingKeyword(String keyword) {     @Override         buyer.should_only_see_results_with_titles_containing(keyword);     protected List<String> storyPaths() {         String codeLocation = codeLocationFromClass(this.getClass()).getFile();     }         return new StoryFinder().findPaths(codeLocation, asList("**/*.story", }                 "**/traders_can_be_subset.story"), asList(""), "file:" + codeLocation);     } }
  32. 32. 32search_by_keyword_and_location.story Scenario: Searching by keyword and location 1 Given Sally wants to buy a puppy for her son When she looks for puppy in the Pets and Animals category Then she should obtain a list of puppy ads public class SearchAdsSteps {     @Steps 2     BuyerSteps buyer;     @Given("Sally wants to buy a $present for her son")     public void buyingAPresent(String present) {         buyer.opens_home_page();     }     @When("she looks for $keyword in the $category category")     public void adSearchByCategoryAndKeyword(String category, String keyword) {         buyer.chooses_category_and_keywords(category, keyword);         buyer.performs_search();     }     @Then("she should obtain a list of $keyword ads")     public void shouldOnlySeeAdsContainingKeyword(String keyword) {         buyer.should_only_see_results_with_titles_containing(keyword);     } 3’ } public class BuyerStories extends ThucydidesJUnitStories { }
  33. 33. 33Now available in JVM flavor!
  34. 34. 34Feature: 1In order to increase sales of advertised articlesAs a sellerI want buyers to be able to easily find ads for articles they wantto buyScenario: Searching by keyword and locationGiven Sally wants to buy a "puppy" for her sonWhen she looks for "puppy" in the "Pets and Animals" categoryThen she should obtain a list of "puppy" ads
  35. 35. 35Scenario: Searching by keyword and locationGiven Sally wants to buy a "puppy" for her sonWhen she looks for "puppy" in the "Pets and Animals" categoryThen she should obtain a list of "puppy" ads Scenario: Searching by keyword and location Given Sally wants to buy a <present> for her son When she looks for <present> in the <category> category Then she should obtain a list of ads for <expected> for sale. Examples: |present |category |expected| |puppy |Pets & Animals | puppies| |kitten |Pets & Animals | kittens| |seiko |Jewellery & Watches| watch |
  36. 36. 36Scenario: Searching by keyword and location 1Given Sally wants to buy a "puppy" for her sonWhen she looks for "puppy" in the "Pets and Animals" categoryThen she should obtain a list of "puppy" adsimport org.junit.runner.RunWith; 2import cucumber.junit.Cucumber;@RunWith(Cucumber.class)@Cucumber.Options(format={"pretty", "html:target/cucumber"})public class RunTests {}
  37. 37. 37Scenario: Searching by keyword and location 1Given Sally wants to buy a "puppy" for her sonWhen she looks for "puppy" in the "Pets and Animals" categoryThen she should obtain a list of "puppy" adsimport org.junit.runner.RunWith; 2import cucumber.junit.Cucumber; public class SearchAdsSteps {     @Steps@RunWith(Cucumber.class) 3     BuyerSteps buyer;@Cucumber.Options(format={"pretty", "html:target/cucumber"})public class RunTests { buy a "([^"]*)" for her son$")     @Given("^Sally wants to}     public void buyingAPresent(String present) {         buyer.opens_home_page();     }     @When("^she looks for "([^"]*)" in the "([^"]*)" category$")     public void adSearchByCategoryAndKeyword(String category, String keyword) {         buyer.chooses_category_and_keywords(category, keyword);         buyer.performs_search();     }     @Then("^she should obtain a list of "([^"]*)" ads$")     public void shouldOnlySeeAdsContainingKeyword(String keyword) {         buyer.should_only_see_results_with_titles_containing(keyword);     } }
  38. 38. 38100% Groovy
  39. 39. 39search_by_keyword_and_location.story scenario "Searching by keyword and location", { given "Sally wants to buy a puppy for her son" when "she looks for puppy in the Pets and Animals category" then "she should obtain a list of ads for puppies for sale" } scenario "Searching by keyword and location", { given "Sally wants to buy a #present for her son" when "she looks for #present in the #category category" then "she should obtain a list of ads for #expected for sale" where "examples should be", { present = [puppy, kitten, seiko] category = [Pets & Animals,Pets & Animals, Jewellery & Watches] expected = [puppies, kittens, watch] } }
  40. 40. 40search_by_keyword_and_location.story scenario "Searching by keyword and location", { 1 given "Sally wants to buy a puppy for her son" when "she looks for puppy in the Pets and Animals category" then "she should obtain a list of ads for puppies for sale" }
  41. 41. 41search_by_keyword_and_location.story scenario "Searching by keyword and location", { 1 given "Sally wants to buy a puppy for her son" when "she looks for puppy in the Pets and Animals category" then "she should obtain a list of ads for puppies for sale" } using "thucydides" 2 thucydides.uses_steps_from BuyerSteps scenario "Searching by keyword and location", { given "Sally wants to buy a puppy for her son", { buyer.opens_home_page() } when "she looks for puppy in the Pets and Animals category", { buyer.chooses_category_and_keywords(category, keyword); buyer.performs_search(); } then "she should obtain a list of ads for puppies for sale",{ buyer.should_only_see_results_with_titles_containing keyword } }
  42. 42. 42Keeping an eye on things
  43. 43. 43(Think “Two-CDs”)
  44. 44. 44Scenario: Searching by keywordGiven Sally wants to buy a puppy for her sonWhen she looks for ads in the Pets & Animals category containing puppyThen she should obtain a list of ads for puppies for sale
  45. 45. 45Scenario: Searching by keywordGiven Sally wants to buy a puppy for her sonWhen she looks for ads in the Pets & Animals category containing puppyThen she should obtain a list of ads for puppies for sale public class SearchAdsSteps {     @Steps     BuyerSteps buyer;     @Given("Sally wants to buy a $present for her son")     public void buyingAPresent(String present) {         buyer.opens_home_page();     }     @When("she looks for $keyword in the $category category")     public void adSearchByCategoryAndKeyword(String category, String keyword) {         buyer.chooses_category_and_keywords(category, keyword);         buyer.performs_search();     }     @Then("she should obtain a list of $keyword ads")     public void shouldOnlySeeAdsContainingKeyword(String keyword) {         buyer.should_only_see_results_with_titles_containing(keyword);     } }
  46. 46. 46public class SearchAdsSteps {    @Steps    BuyerSteps buyer;    @Given("Sally wants to buy a $present for her son")    public void buyingAPresent(String present) {        buyer.opens_home_page();    } public class BuyerSteps extends ScenarioSteps {    @When("she looks for $keyword in the $category category")    public     HomePage homePage; void adSearchByCategoryAndKeyword(String category, String keyword) {     SearchResultsPage searchResultsPage;        buyer.chooses_category_and_keywords(category, keyword);        buyer.performs_search();     public BuyerSteps(Pages pages) {    }         super(pages);         homePage = getPages().get(HomePage.class);    @Then("she should obtain a list getPages().get(SearchResultsPage.class);         searchResultsPage = of $keyword ads")    public     } shouldOnlySeeAdsContainingKeyword(String keyword) { void        buyer.should_only_see_results_with_titles_containing(keyword);    }     @Step     public void opens_home_page() {}         homePage.open();     }     @Step     public void chooses_region(String region) {         homePage.chooseRegion(region);     }     @Step     public void chooses_category_and_keywords(String category, String keywords) {         homePage.chooseCategoryFromDropdown(category);         homePage.enterKeywords(keywords);     }
  47. 47. 47
  48. 48. 48
  49. 49. 49
  50. 50. 50
  51. 51. 51
  52. 52. 52
  53. 53. From Acceptance Tests to Developer Tests
  54. 54. BDD - A Development Tool
  55. 55. TDD or BDD?
  56. 56. Make it passWrite a failing test TDD Refactor What test should I write?
  57. 57. Acceptance Tests (high level features) Spock Developer Tests (low level features) What features should I implement?etc.
  58. 58. Goal: In order to increase revenue from commissions on classified ads salesAs the head of the classified ads departmentI want to increase the number of items sold via our classified ads Story: In order to find the items I am interested in faster Acceptance   As a buyer I want to be able to list all the ads with a particular keyword in the description or title. Tests Scenario: Searching by keyword and location Scenario: Searching by keyword and location Scenario: Searching by keyword Given Sally wants to buy a apuppyfor her son Given Sally wants to buy apuppy for her son Given Sally wants to buy puppy for her son When she looks for ads ininthePets & Animals category containing puppy When she looks for ads inthe Pets & Animals category containing puppy When she looks for ads the Pets & Animals category containing puppy inThen she should obtain a list of ads for puppies for sale inNew South Wales New South Wales class WhenCalculatingGST extends Specification { class WhenCalculatingGST extends Specification { class WhenCalculatingGST extends Specification {     def "GST should apply on ordinary articles"() {         given: should apply on ordinary articles"() { {     def "GST "we are selling a shirt"         given: should apply on ordinary articles"()     def "GST "we are selling a shirt" Developer               def sale = Sale.of(1,"shirt").forANetPriceOf(10.00)             def sale areSale.of(1,"shirt").forANetPriceOf(10.00)         given: "we = selling a shirt"         when: "we calculate the price including GST"             def sale = Sale.of(1,"shirt").forANetPriceOf(10.00)             def "we calculate sale.totalPrice         when: totalPrice = the price including GST"             def "we calculate the price GST of         when: totalPrice including GST"         then: "the totalPrice= =sale.totalPrice 10%"             def price should sale.totalPrice include             totalPrice == should include GST of 10%"         then: "the price 11.00 include GST of 10%"         then: "the price should             totalPrice == 11.00 Tests     }             totalPrice == 11.00 }     } }     } }
  59. 59. Unit Tests Acceptance tests
  60. 60. Spock - BDD for developers
  61. 61. Spockclass WhenCalculatingGST extends Specification {    def "GST should apply on ordinary articles"() {        given: "we are selling a shirt"            def sale = Sale.of(1,"shirt").forANetPriceOf(10.00)        when: "we calculate the price including GST"            def totalPrice = sale.totalPrice        then: "the price should include GST of 10%"            totalPrice == 11.00    }} Given-When-Then structure
  62. 62. Spockclass WhenCalculatingGST extends Specification {    ...    def "GST should not apply on GST-exempt articles"() {        given: "we are selling a bottle of milk"          def sale = Sale.of(1,"shirt").forANetPriceOf(5.00)        when: "we calculate the price including GST"            def totalPrice = sale.totalPrice        then: "the price should not include GST%"            totalPrice == 5.00    }} Meaningful error messages
  63. 63. Spock Lightweight stubbingclass WhenCalculatingGST extends Specification {    def "GST should apply on ordinary articles"() {        given: "GST is at 12.5%"            def gstRateProvider = Mock(GSTRateProvider)            gstRateProvider.getRate() >> 0.125            Sales sales = new Sales(gstRateProvider)        and: "we are selling a shirt"            def sale = sales.makeSaleOf(1,"shirt").forANetPriceOf(10.00)        when: "we calculate the price including GST"            def totalPrice = sale.totalPrice        then: "the price should include GST of 12.5%"            totalPrice == 11.25    }}
  64. 64. Spockclass WhenDeliveringSoldItems extends Specification {    def gstRateProvider = Mock(GSTRateProvider)    def deliveryService = Mock(DeliveryService)    def "Sold articles should be delivered"() {        given: "we are selling shirts online"            Sales sales = new Sales(gstRateProvider, deliveryService)        when: "we sell a shirt"            sales.makeSaleOf(1,"shirt").forANetPriceOf(10.00)        then: "the shirt should be sent to the delivery service"            1 * deliveryService.dispatch(_)    }} Lightweight mocking
  65. 65. Spockclass WhenDisplayingTagNamesInAReadableForm extends Specification {    def inflection = Inflector.instance    def "should transform singular nouns into plurals"() {        when: "I find the plural form of a single word"            def pluralForm = inflection.of(singleForm).inPluralForm().toString();        then: "the plural form should be gramatically correct"            pluralForm == expectedPluralForm        where:            singleForm | expectedPluralForm            epic | epics            feature | features            story | stories            stories | stories            octopus | octopi            sheep | sheep    }} Data-driven tests
  66. 66. Spec2 - BDD for Scala
  67. 67. class  WhenCalculatingGST  extends  Specification  {  sequential    "GST  should  apply  on  ordinary  articles"  >>  {        "Given  we  are  selling  a  shirt"  >>  {            sale  =  Sale.of(1,  "shirt").forANetPriceOf(10.00)        }        "When  we  calculate  the  price  including  GST"  >>  {            totalPrice  =  sale.totalPrice        }        "Then  the  price  should  include  a  GST  of  10%"  >>  {            totalPrice  ===  11.00        }    }    var  sale  =  Sale();  var  totalPrice  =  0.0}
  68. 68. class  WhenCalculatingGST2  extends  Specification  with  Mockito  {  sequential    "GST  should  apply  on  ordinary  articles"  >>  { Lightweight        "Given  we  are  selling  a  shirt"  >>  { stubbing DSL            val  sales  =  Sales(mock[GSTProvider])            sales.gstProvider.rate  returns  12.5            sale  =  sales.makeSaleOf(1,  "shirt").forANetPriceOf(10.00)        }        "When  we  calculate  the  price  including  GST"  >>  {            totalPrice  =  sale.totalPrice        }        "Then  the  price  should  include  a  GST  of  12.5%"  >>  {            totalPrice  ===  11.25        }    }    var  sale  =  Sale();  var  totalPrice  =  0.0}
  69. 69. class  WhenDeliveringSoldItems  extends  Specification  with  Mockito  {  sequential    "Sold  articles  should  be  delivered"  >>  {        "Given  we  are  selling  shirts  online"  >>  {            sales  =  Sales(mock[GSTProvider],  mock[DeliveryService])        }        "When  we  sell  a  shirt"  >>  {            sale  =  sales.makeSaleOf(1,  "shirt").forANetPriceOf(10.00)        }        "Then  the  shirt  should  be  sent  to  the  delivery  service"  >>  {            there  was  one(sales.deliveryService).dispatch(anyString)        }    } Lightweight    var  sale  =  Sale();  var  sales  =  Sales() mocking DSL}
  70. 70. class  WhenDisplayingTagNamesInAReadableForm  extends  Specification  with  Tables  {    "The  inflector  should  transform  singular  nouns  into  plurals"  >>  {                                                                                                                                """        when  I  find  the  plural  form  of  a  single  word,  then  the  plural  form  should  be        gramatically  correct:                                                                                                                                """  >>  {            "single  form"    |  "plural  form"    |>            "epic"                  !  "epics"                |            "feature"            !  "features"          | Data-driven tests,            "story"                !  "story"                | Scala-style            "stories"            !  "stories"            |            "octopus"            !  "octopi"              |            "sheep"                !  "sheep"                |  {  (singleForm,  pluralForm)  =>                Inflection.of(singleForm).inPluralForm.toString  ===  pluralForm            }        }    }}
  71. 71. Jasmine - BDD for Javascript
  72. 72. describe( "temperature converter", function () {    it("converts fahrenheit to celsius", function () {        expect(Convert(50, "F").to("C")).toEqual(10);    });}); Simple assertion structure
  73. 73. describe( "temperature converter", function () {    it("converts fahrenheit to celsius", function () {        expect(Convert(50, "F").to("C")).toEqual(10);    });      it("converts celsius to fahrenheit", function () {        expect(Convert(30, "C").to("F")).toEqual(86);    });}); More complex behavior
  74. 74. describe( "converter library", function () {    describe( "temperature converter", function () {        it("converts fahrenheit to celsius", function () {            expect(Convert(50, "F").to("C")).toEqual(10);        });          it("converts celsius to fahrenheit", function () {            expect(Convert(30, "C").to("F")).toEqual(86);        });    });    describe( "weight converter", function () {        it("converts kilograms to pounds", function () {            expect(Convert(100, "KG").to("LB")).toEqual(220);        });    });}); Nested behaviors
  75. 75. And it works with Maven!
  76. 76. Evaluate test results in a browser
  77. 77. Evaluate test results in a browser
  78. 78. Generate JUnit-compatible results
  79. 79. hAp://try-­‐jasmine.heroku.com/
  80. 80. In conclusion...It’s behavior allthe way down
  81. 81. Thank You John  Ferguson  Smart

×