Download - Cucumber
![Page 1: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/1.jpg)
Writing runnable acceptance criteria in plain text with
Farooq Ali
![Page 2: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/2.jpg)
The YawningCrevasse of Doom
![Page 3: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/3.jpg)
fluffy high-level needs
![Page 4: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/4.jpg)
<technical_babble />
![Page 5: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/5.jpg)
[Test][ExpectedException(typeof(InsufficientFundsException))]public void TransferWithInsufficientFunds(){
Account source = new Account();source.Deposit(200.00F);Account destination = new Account();destination.Deposit(150.00F);
}
![Page 6: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/6.jpg)
![Page 7: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/7.jpg)
the convergence of two movements
![Page 8: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/8.jpg)
the convergence of two movementsBehavior-Driven Development (BDD)& Domain-Specific Languages (DSLs)
![Page 9: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/9.jpg)
BDD movement
“Acceptance criteria should be executable”
“…a ubiquitous language for analysis”
![Page 10: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/10.jpg)
what are we really trying to describe?
![Page 11: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/11.jpg)
what are we really trying to describe?
the human concept of causality
![Page 12: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/12.jpg)
Precondition -> Given
Action -> When
Outcome -> Then
Causality
![Page 13: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/13.jpg)
Setup Data/State -> Given
Call Method -> When
Assert -> Then
Causality
![Page 14: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/14.jpg)
“…a computer language that's targeted to a particular kind of problem, rather than a general purpose language that's aimed at any kind of software problem.”
DSL movement
![Page 15: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/15.jpg)
“The sweet spot, however is in making DSLs business-readable rather than business-writeable.”
DSL movement
![Page 16: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/16.jpg)
BDD + DSL
![Page 17: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/17.jpg)
Feature: AdditionAs a math moronI want to add two numbers togetherSo that I can better use my scarce brain processing power Scenario: Adding positive numbers together Given I enter 1 into the calculator When I add 1 to it Then the calculator should show 2
Gherkin
![Page 18: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/18.jpg)
Acceptance Criteria
![Page 19: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/19.jpg)
Shared Vocabulary
![Page 20: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/20.jpg)
Documentation
![Page 21: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/21.jpg)
Traceability
![Page 22: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/22.jpg)
Bug Tracking
![Page 23: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/23.jpg)
Using Cucumber
![Page 24: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/24.jpg)
Acceptance Criteria(Plain Text)
Step Definitions(Ruby)
ComponentsBuilding Blocks
![Page 25: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/25.jpg)
Acceptance Criteria
Feature: AdditionAs a math moronI want to add two numbers togetherSo that I can better use my scarce brain processing power Scenario: Adding positive numbers together Given I enter 1 into the calculator When I add 1 to it Then the calculator should show 2
Acceptance Criteria
![Page 26: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/26.jpg)
Acceptance Criteria
Feature: AdditionAs a math moronI want to add two numbers togetherSo that I can better use my scarce brain processing power Scenario: Adding positive numbers together Given I enter 1 into the calculator When I add 1 to it Then the calculator should show 2
Acceptance Criteria
![Page 27: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/27.jpg)
Acceptance Criteria
Feature: AdditionAs a math moronI want to add two numbers togetherSo that I can better use my scarce brain processing power Scenario: Adding positive numbers together Given I enter 1 into the calculator When I add 1 to it Then the calculator should show 2
Acceptance Criteria
![Page 28: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/28.jpg)
Acceptance Criteria
Feature: AdditionAs a math moronI want to add two numbers togetherSo that I can better use my scarce brain processing power Scenario: Adding positive numbers together Given I enter 1 into the calculator When I add 1 to it Then the calculator should show 2
Acceptance Criteria
![Page 29: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/29.jpg)
Acceptance Criteria
Feature: AdditionAs a math moronI want to add two numbers togetherSo that I can better use my scarce brain processing power Scenario: Adding positive numbers together Given I enter 1 into the calculator When I add 1 to it Then the calculator should show 2
Acceptance Criteria
![Page 30: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/30.jpg)
KeywordsKeyword Localized
name ‘English’
native ‘English’
encoding ‘UTF-8’
feature ‘Feature’
background ‘Background’
scenario ‘Scenario’
scenario_outline ‘Scenario Outline’
examples ‘Examples’
given ‘Given’
when ‘When’
then ’Then’
and ‘And’
but ‘But’
Keywords
![Page 31: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/31.jpg)
LanguagesMacintosh-9:calculator ThoughtWorks$ cucumber --language help| ar | Arabic | العربية| bg | Bulgarian | български | cat | Catalan | català | cy | Welsh | Cymraeg | cz | Czech | Česky | da | Danish | dansk | de | German | Deutsch | en | English | English | en-au | Australian | Australian | en-lol | LOLCAT | LOLCAT | en-tx | Texan | Texan | es | Spanish | español | et | Estonian | eesti keel | fi | Finnish | suomi | fr | French | français | he | Hebrew | עברית | hr | Croatian | hrvatski | hu | Hungarian | magyar | id | Indonesian | Bahasa Indonesia
Languages
![Page 32: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/32.jpg)
Given I enter 1 into the calculatorWhen I add 1 to itThen the calculator should show 2
Acceptance Criteria(Plain Text)
Step DefinitionsBuilding Blocks
![Page 33: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/33.jpg)
Given I enter 1 into the calculatorWhen I add 1 to itThen the calculator should show 2
Given /^I enter (.+) into the calculator$/ do |number| @calculator = Calculator.new @calculator.enter(number.to_i)end
When /^I add (.+) to it$/ do |number| @calculator.add(number.to_i)end
When /^the calculator should show (.+)$/ do |number| @calculator.number.should == number.to_iend
Acceptance Criteria(Plain Text)
Step Definitions(Ruby)
Step DefinitionsBuilding Blocks
![Page 34: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/34.jpg)
Step Definitions
Given /^I enter (.+) into the calculator$/ do |number| @calculator = Calculator.new @calculator.enter(number.to_i)end
When /^I add (.+) to it$/ do |number| @calculator.add(number.to_i)end
Then /^the calculator should show (.+)$/ do |number| @calculator.number.should == number.to_iend
Step Definitions
![Page 35: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/35.jpg)
Step Definitions
Then /^the calculator should show (.+)$/ do |number| @calculator.number.should == number.to_iend
Step Definitions
![Page 36: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/36.jpg)
Step DefinitionsStep Definitions
When I give a 45-minute long talk on Cucumber at 10:30am
![Page 37: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/37.jpg)
Step DefinitionsStep Definitions
When I give a 45-minute long talk on Cucumber at 10:30am
![Page 38: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/38.jpg)
Step Definitions
/I give a (\d+)-minute long talk on (.+) at (\d+):(\d+)(am|pm)/
Step Definitions
When I give a 45-minute long talk on Cucumber at 10:30am
![Page 39: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/39.jpg)
Step Definitions
/I give a (\d+)-minute long talk on (.+) at (\d+):(\d+)(am|pm)/
Step Definitions
When I give a 45-minute long talk on Cucumber at 10:30am
![Page 40: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/40.jpg)
Step DefinitionsStep Definitions
do |duration_in_minutes, topic, start_hour, start_minute, am_pm| end
/I give a (\d+)-minute long talk on (.+) at (\d+):(\d+)(am|pm)/
When I give a 45-minute long talk on Cucumber at 10:30am
![Page 41: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/41.jpg)
Multiple Given-When-Thens
Scenario: Multiple Givens Given one thing Given another thing Given yet another thing When I open my eyes Then I see something Then I don't see something else
Multiple Given-When-Thens
![Page 42: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/42.jpg)
Or use And / But
Scenario: Multiple Givens Given one thing And another thing And yet another thing When I open my eyes Then I see something But I don't see something else
Or use And/But
![Page 43: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/43.jpg)
Reuse
Given /^the user (.*) exists$/ do |name|#...
end
Given /^I log in as (.*)$/ do |name| #...end
Given /^(.*) is logged in$/ do |name| Given "the user #{name} exists" Given "I log in as #{name}"end
Calling steps from within steps
![Page 44: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/44.jpg)
ReuseMultiline step arguments - Tables
Given the following people exist: | name | email | phone | | Farooq | [email protected] | 123 | | Mary | [email protected] | 234 | | Bob | [email protected] | 456 |
![Page 45: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/45.jpg)
ReuseMultiline step arguments - Tables
Given the following people exist: | name | email | phone | | Farooq | [email protected] | 123 | | Mary | [email protected] | 234 | | Bob | [email protected] | 456 |
Given /the following people exist:/ do |people_table| people_table.hashes.each do |hash| # 1st: {'name' => ’Farooq', 'email' => ’[email protected]’, ... } # 2nd: {'name' => ’Mary', 'email' => ’[email protected]', ... } # ... endend
![Page 46: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/46.jpg)
ReuseMultiline step arguments - Strings
Given a blog post named "Random" with Markdown body """ Some Title, Eh? ============== Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet, consectetur adipiscing elit. """
![Page 47: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/47.jpg)
ReuseMultiline step arguments - Strings
Given a blog post named "Random" with Markdown body """ Some Title, Eh? ============== Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet, consectetur adipiscing elit. """
Given /^a blog post named "([^\"]*)" with Markdown body$/ do |title, markdown| Post.create!(:title => title, :body => markdown)end
![Page 48: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/48.jpg)
Tags
@billingFeature: Enter billing info
@creditcard Scenario: Credit card @paypal Scenario: PayPal
Tags
![Page 49: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/49.jpg)
Hooks
Before do # do something before first step of scenarioend
After do # do something after each scenarioend
Hooks
![Page 50: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/50.jpg)
Tagged Hooks
Before('@billing', '@calculations') do # This will only run before scenarios tagged
# with @billing or @calculations. end
Tagged Hooks
![Page 51: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/51.jpg)
Global Hooks
browser = Selenium::SeleniumDriver.new("localhost", 4444, "*chrome",
"http://localhost", 15000)
Given 'I am on the Google search page' do browser.open('http://www.google.com/’)end
When /I search for "(.*)"/ do |query| browser.type('q', query) browser.click 'btnG’ browser.wait_for_page_to_loadend
Then /I should see a link to (.*)/ do |expected_url| browser.is_element_present("css=a[href='#{expected_url}']").should be_trueend
Global Hooks
![Page 52: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/52.jpg)
Tags
Feature: Multiple site support As a Mephisto site owner I want to host blogs for different people In order to make gigantic piles of money
Background: Given a global administrator named “Greg” And a blog named “Greg’s anti-tax rants” And a customer named “Dr. Bill” And a blog named “Expensive Therapy” owned by “Dr. Bill”
Scenario: Dr. Bill posts to his own blog Given I am logged in as Dr. Bill When I try to post to “Expensive Therapy” Then I should see “Your article was published.”
Backgrounds
![Page 53: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/53.jpg)
Global Hooks
# support fileTransform /^user (\w+)$/ do |username| User.find_by_username(username) end
# step definition fileThen /^(user \w+) should be friends with (user \w+)$/ do |user,friend| user.should be_friends_with(friend)end
Step Argument Transforms
![Page 54: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/54.jpg)
Formatters
cucumber -f junit -–out <output_dir>
![Page 55: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/55.jpg)
Formatters: StepsFeature: --formatter steps option - Steps Formatter
In order to easily see which steps are already defined, specially when using 3rd party steps libraries, Cucumber should show the available steps in a user-friendly format
Background: Given I am in steps_library
Scenario: Printing steps When I run cucumber -f steps features Then it should pass with """ features/step_definitions/steps_lib1.rb /^I defined a first step$/ # features/step_definitions/steps_lib1.rb:1 /^I define a second step$/ # features/step_definitions/steps_lib1.rb:4 /^I should also have a third step$/ # features/step_definitions/steps_lib1.rb:7 features/step_definitions/steps_lib2.rb /^I defined a step 4$/ # features/step_definitions/steps_lib2.rb:1 /^I create a step 5$/ # features/step_definitions/steps_lib2.rb:4 /^I should be too tired for step 6$/ # features/step_definitions/steps_lib2.rb:7 6 step definition(s) in 2 source file(s).
"""
![Page 56: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/56.jpg)
Formatters : JUnitFeature: JUnit output formatter In order for developers to create test reports with ant Cucumber should be able to output JUnit xml files Background: Given I am in junit And the tmp directory is empty @mri186 Scenario: one feature, one passing scenario, one failing scenario When I run cucumber --format junit --out tmp/ features/one_passing_one_failing.feature Then it should fail with """
""" And "examples/junit/tmp/TEST-one_passing_one_failing.xml" with junit duration "0.005" should contain """ <?xml version="1.0" encoding="UTF-8"?> <testsuite errors="0" failures="1" name="One passing scenario, one failing scenario" tests="2"
time="0.005"> <testcase classname="One passing scenario, one failing scenario.Passing" name="Passing"
time="0.005"> </testcase> <testcase classname="One passing scenario, one failing scenario.Failing" name="Failing"
time="0.005"> <failure message="failed Failing" type="failed"> Scenario: Failing
Given a failing scenario
Message: (RuntimeError) features/one_passing_one_failing.feature:7:in `Given a failing scenario' </failure> </testcase> </testsuite>
""" Scenario: pending steps are simply skipped When I run cucumber --format junit --out tmp/ features/pending.feature Then it should pass with """ """ And "examples/junit/tmp/TEST-pending.xml" with junit duration "0.009" should contain """ <?xml version="1.0" encoding="UTF-8"?> <testsuite errors="0" failures="0" name="Pending step" tests="0" time="0.009"> </testsuite> """
Scenario: pending step with strict option should fail When I run cucumber --format junit --out tmp/ features/pending.feature --strict Then it should fail with """
""" And "examples/junit/tmp/TEST-pending.xml" with junit duration "0.000160" should contain """ <?xml version="1.0" encoding="UTF-8"?> <testsuite errors="0" failures="1" name="Pending step" tests="1" time="0.000160"> <testcase classname="Pending step.Pending" name="Pending" time="0.000160"> <failure message="pending Pending" type="pending"> Scenario: Pending
TODO (Cucumber::Pending) features/pending.feature:4:in `Given a pending step' </failure> </testcase> </testsuite>
""" Scenario: run all features When I run cucumber --format junit --out tmp/ features Then it should fail with """ """ And "examples/junit/tmp/TEST-one_passing_one_failing.xml" should exist And "examples/junit/tmp/TEST-pending.xml" should exist Scenario: show correct error message if no --out is passed When I run cucumber --format junit features Then STDERR should not match """can't convert .* into String \(TypeError\) """ And STDERR should match """You \*must\* specify \-\-out DIR for the junit formatter """
![Page 57: Cucumber](https://reader033.vdocuments.us/reader033/viewer/2022061111/54551433af79591a248b6206/html5/thumbnails/57.jpg)
Formatters : HTML
Feature: HTML formatter In order to make it easy to read Cucumber results there should be a HTML formatter with an awesome CSS
Scenario: Everything in examples/self_test When I run cucumber -q --format html --out tmp/a.html features Then "examples/self_test/tmp/a.html" should have the same contents as
"features/html_formatter/a.html"