cucumber

Post on 02-Nov-2014

13 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

Writing runnable acceptance criteria in plain text with Cucumber.

TRANSCRIPT

Writing runnable acceptance criteria in plain text with

Farooq Ali

The YawningCrevasse of Doom

fluffy high-level needs

<technical_babble />

[Test][ExpectedException(typeof(InsufficientFundsException))]public void TransferWithInsufficientFunds(){

Account source = new Account();source.Deposit(200.00F);Account destination = new Account();destination.Deposit(150.00F);

}

the convergence of two movements

the convergence of two movementsBehavior-Driven Development (BDD)& Domain-Specific Languages (DSLs)

BDD movement

“Acceptance criteria should be executable”

“…a ubiquitous language for analysis”

what are we really trying to describe?

what are we really trying to describe?

the human concept of causality

Precondition -> Given

Action -> When

Outcome -> Then

Causality

Setup Data/State -> Given

Call Method -> When

Assert -> Then

Causality

“…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

“The sweet spot, however is in making DSLs business-readable rather than business-writeable.”

DSL movement

BDD + DSL

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

Acceptance Criteria

Shared Vocabulary

Documentation

Traceability

Bug Tracking

Using Cucumber

Acceptance Criteria(Plain Text)

Step Definitions(Ruby)

ComponentsBuilding Blocks

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

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

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

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

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

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

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

Given I enter 1 into the calculatorWhen I add 1 to itThen the calculator should show 2

Acceptance Criteria(Plain Text)

Step DefinitionsBuilding Blocks

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

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

Step Definitions

Then /^the calculator should show (.+)$/ do |number| @calculator.number.should == number.to_iend

Step Definitions

Step DefinitionsStep Definitions

When I give a 45-minute long talk on Cucumber at 10:30am

Step DefinitionsStep Definitions

When I give a 45-minute long talk on Cucumber at 10:30am

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

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

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

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

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

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

ReuseMultiline step arguments - Tables

Given the following people exist: | name | email | phone | | Farooq | farooq@email.com | 123 | | Mary | mary@email.com | 234 | | Bob | bob@email.org | 456 |

ReuseMultiline step arguments - Tables

Given the following people exist: | name | email | phone | | Farooq | farooq@email.com | 123 | | Mary | mary@email.com | 234 | | Bob | bob@email.org | 456 |

Given /the following people exist:/ do |people_table| people_table.hashes.each do |hash| # 1st: {'name' => ’Farooq', 'email' => ’farooq@email.com’, ... } # 2nd: {'name' => ’Mary', 'email' => ’mary@email.com', ... } # ... endend

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. """

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

Tags

@billingFeature: Enter billing info

@creditcard Scenario: Credit card @paypal Scenario: PayPal

Tags

Hooks

Before do # do something before first step of scenarioend

After do # do something after each scenarioend

Hooks

Tagged Hooks

Before('@billing', '@calculations') do # This will only run before scenarios tagged

# with @billing or @calculations. end

Tagged Hooks

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

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

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

Formatters

cucumber -f junit -–out <output_dir>

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).

"""

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 """

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"

top related