Bdd state-of-the-union
-
Upload
wakaleo-consulting -
Category
Documents
-
view
2.049 -
download
0
Transcript of Bdd state-of-the-union
![Page 1: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/1.jpg)
John Ferguson Smart
Behavior-Driven Development on the JVMA State of the Union
![Page 2: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/2.jpg)
John Ferguson Smart
ConsultantTrainerMentorAuthorSpeakerCoder
![Page 3: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/3.jpg)
What is BDD?
![Page 4: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/4.jpg)
Common Language
Business Developer
Business Analyst
Tester
![Page 5: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/5.jpg)
Executable Specifications
![Page 6: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/6.jpg)
OutsideIn
![Page 7: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/7.jpg)
Value Driven
![Page 8: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/8.jpg)
\So why use BDD?
Only build features that add real value
Less wasted effort
Better communication
Higher quality, better tested product
Traceability
![Page 9: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/9.jpg)
BDD - Requirements Analysis and Communication
![Page 10: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/10.jpg)
Examples/Scenarios
Stories
Features
Capabilities
Goals
Acceptance Criteria
![Page 11: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/11.jpg)
11
“We are going to build an online classifieds website”
Successful projects start with a shared vision
![Page 12: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/12.jpg)
12
You 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.”
![Page 13: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/13.jpg)
A good goal should add value to the businessIncrease revenueReduce costsAvoid future costsProtect revenue
Determining the value of a goal
“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”
![Page 14: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/14.jpg)
What does the customer really need?
I want users to be able to search for products by keyword Why?
So that potential buyers can find the articles they want
So that our sellers can sell their stuff fasterWhy?
Why?
So that they keep selling their stuff on our siteWhy?
So that we keep earning money when they post their ads with us
![Page 15: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/15.jpg)
What does the customer really need?
Good teams push back!Users tend to express requirements as implementationsWe 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 sellersBuyers 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
![Page 16: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/16.jpg)
“Let’s get more sales for our advertisers by making the ads easier to find online.”
Notify potential buyers about new itemsIn order to increase sales of advertised articlesAs a sellerI want previous buyers to know about new items that they might be interested in buying
Search for online adsIn order to increase sales of advertised articlesAs a sellerI want buyers to be able to easily find ads for articles they want to buy
Features and capabilities help deliver these goals
![Page 17: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/17.jpg)
Feature Injection - what features do you do first?
Our goals say what business value we need to deliverWe implement the minimum features required to deliver this business value
Search for online adsIn order to increase sales of advertised articlesAs a sellerI want buyers to be able to easily find ads for articles they want to buy
The goal comes first
The stakeholder is secondary
The feature must be required to achieve the goal
![Page 18: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/18.jpg)
18
We use examples and stories to explore the features
“Searching by category”
Search for online ads
“Searching by keyword and category”
![Page 19: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/19.jpg)
19
We use examples and stories to explore the features
Search for online ads
Searching by keyword and locationGiven 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.
![Page 20: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/20.jpg)
20
Examples and scenarios become acceptance criteria
Acceptance Criteria illustrate and validate the stories
Searching by keyword and locationGiven 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 Keywordspuppy Pets & Animals labradorkitten Pets & Animals burmesekitten Toys fluffy cat
![Page 21: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/21.jpg)
Organize your requirements
![Page 22: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/22.jpg)
Requirements can come from many sources...
![Page 23: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/23.jpg)
CapabilityIn order to increase the number of items I sellAs a sellerI want buyers to be able to view ads for items they might want to purchase
FeatureIn order to increase sales of advertised articlesAs a sellerI want potential buyers to be able to display only the ads for articles that they might be interested in purchasing.
StoryIn order to find the items I am interested in fasterAs a buyerI want to be able to list all the ads with a particular keyword in the description or title.
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
Keep them organized!
![Page 24: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/24.jpg)
Requirements can come from many sources...
![Page 25: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/25.jpg)
25
BDD - Test Automation and Beyond
![Page 26: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/26.jpg)
26
The original Java BDD framework
![Page 27: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/27.jpg)
27
Narrative:In order to increase sales of advertised articlesAs a sellerI 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.
search_by_keyword_and_location.story
![Page 28: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/28.jpg)
28
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.
search_by_keyword_and_location.story
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 |
![Page 29: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/29.jpg)
29
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.
search_by_keyword_and_location.story
1
![Page 30: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/30.jpg)
30
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 puppy ads
search_by_keyword_and_location.story
1
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); }}
2
![Page 31: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/31.jpg)
31
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 puppy ads
search_by_keyword_and_location.story
1
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); }}
2public class BuyerStories extends JUnitStories { public BuyerStories() { configuredEmbedder().embedderControls().doGenerateViewAfterStories(true).doIgnoreFailureInStories(false) .doIgnoreFailureInView(true).doVerboseFailures(true).useThreads(2).useStoryTimeoutInSecs(60); }
@Override public Configuration configuration() { return new MostUsefulConfiguration(); }
@Override public InjectableStepsFactory stepsFactory() { return new InstanceStepsFactory(configuration(), new TraderSteps(new TradingService()), new AndSteps()); }
@Override 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); }}
3
![Page 32: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/32.jpg)
32
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 puppy ads
search_by_keyword_and_location.story
1
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); }}
public class BuyerStories extends ThucydidesJUnitStories {}
3’
2
![Page 33: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/33.jpg)
33
Now available in JVM flavor!
![Page 34: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/34.jpg)
34
Feature:In order to increase sales of advertised articlesAs a sellerI 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 "puppy" ads
1
![Page 35: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/35.jpg)
35
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 "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 |
![Page 36: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/36.jpg)
36
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 "puppy" ads
import org.junit.runner.RunWith;import cucumber.junit.Cucumber;
@RunWith(Cucumber.class)@Cucumber.Options(format={"pretty", "html:target/cucumber"})public class RunTests {}
1
2
![Page 37: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/37.jpg)
37
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 "puppy" ads
import org.junit.runner.RunWith;import cucumber.junit.Cucumber;
@RunWith(Cucumber.class)@Cucumber.Options(format={"pretty", "html:target/cucumber"})public class RunTests {}
1
2public class SearchAdsSteps { @Steps BuyerSteps buyer;
@Given("^Sally wants to buy a \"([^\"]*)\" for her son$") 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); }}
3
![Page 38: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/38.jpg)
38
100% Groovy
![Page 39: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/39.jpg)
39
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"}
search_by_keyword_and_location.story
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'] }}
![Page 40: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/40.jpg)
40
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"}
search_by_keyword_and_location.story
1
![Page 41: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/41.jpg)
41
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"}
search_by_keyword_and_location.story
1
using "thucydides"
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 }}
2
![Page 42: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/42.jpg)
42
Keeping an eye on things
![Page 43: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/43.jpg)
43
(Think “Two-CDs”)
![Page 44: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/44.jpg)
44
Scenario: 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
![Page 45: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/45.jpg)
45
Scenario: 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 salepublic 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); }}
![Page 46: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/46.jpg)
46
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); }}
public class BuyerSteps extends ScenarioSteps {
HomePage homePage; SearchResultsPage searchResultsPage;
public BuyerSteps(Pages pages) { super(pages); homePage = getPages().get(HomePage.class); searchResultsPage = getPages().get(SearchResultsPage.class); }
@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); }
![Page 47: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/47.jpg)
47
![Page 48: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/48.jpg)
48
![Page 49: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/49.jpg)
49
![Page 50: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/50.jpg)
50
![Page 51: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/51.jpg)
51
![Page 52: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/52.jpg)
52
![Page 53: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/53.jpg)
From Acceptance Tests to Developer Tests
![Page 54: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/54.jpg)
BDD - A Development Tool
![Page 55: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/55.jpg)
TDD or BDD?
![Page 56: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/56.jpg)
Write a failing test
Make it pass
Refactor
TDD
What test should I write?
![Page 57: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/57.jpg)
Developer Tests (low level features)
Acceptance Tests (high level features)
etc.
Spock
What features should I implement?
![Page 58: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/58.jpg)
Story: In order to find the items I am interested in fasterAs a buyerI want to be able to list all the ads with a particular keyword in the description or title.
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
Scenario: Searching by keyword and locationGiven Sally wants to buy a puppy for her sonWhen she looks for ads in the Pets & Animals category containing puppy in New South Wales
Scenario: Searching by keyword and locationGiven Sally wants to buy a puppy for her sonWhen she looks for ads in the Pets & Animals category containing puppy in New South Wales
Scenario: 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
Acceptance Tests
Developer Tests
class 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 }}
class 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 }}
class 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 }}
![Page 59: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/59.jpg)
Unit Tests Acceptance tests
![Page 60: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/60.jpg)
Spock - BDD for developers
![Page 61: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/61.jpg)
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
![Page 62: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/62.jpg)
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
![Page 63: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/63.jpg)
Spock
class 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 }}
Lightweight stubbing
![Page 64: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/64.jpg)
Spock
class 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
![Page 65: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/65.jpg)
class 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' }}
Spock
Data-driven tests
![Page 66: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/66.jpg)
Spec2 - BDD for Scala
![Page 67: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/67.jpg)
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}
![Page 68: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/68.jpg)
class WhenCalculatingGST2 extends Specification with Mockito { sequential
"GST should apply on ordinary articles" >> { "Given we are selling a shirt" >> { 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}
Lightweight stubbing DSL
![Page 69: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/69.jpg)
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) } }
var sale = Sale(); var sales = Sales()}
Lightweight mocking DSL
![Page 70: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/70.jpg)
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" | "story" ! "story" | "stories" ! "stories" | "octopus" ! "octopi" | "sheep" ! "sheep" | { (singleForm, pluralForm) =>
Inflection.of(singleForm).inPluralForm.toString === pluralForm
} } }}
Data-driven tests, Scala-style
![Page 71: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/71.jpg)
Jasmine - BDD for Javascript
![Page 72: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/72.jpg)
describe( "temperature converter", function () { it("converts fahrenheit to celsius", function () { expect(Convert(50, "F").to("C")).toEqual(10); }); });
Simple assertion structure
![Page 73: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/73.jpg)
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
![Page 74: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/74.jpg)
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
![Page 75: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/75.jpg)
And it works with Maven!
![Page 76: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/76.jpg)
Evaluate test results in a browser
![Page 77: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/77.jpg)
Evaluate test results in a browser
![Page 78: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/78.jpg)
Generate JUnit-compatible results
![Page 80: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/80.jpg)
It’s behavior all the way down
In conclusion...
![Page 81: Bdd state-of-the-union](https://reader030.fdocuments.in/reader030/viewer/2022032514/55d516b9bb61eb8a6b8b471d/html5/thumbnails/81.jpg)
Thank You
John Ferguson Smart