SlideShare a Scribd company logo
1 of 148
Download to read offline
Automating the Requirements
 Language You Already Speak
         Ben Mabey
         @bmabey
Developer        Tester




      Product Manager
                        Designer/UX
Requirements
56% of all bugs are introduced in
requirements. (CHAOS Report)
45% of functionality is never used
Only 20% makes up core
functionality that is ā€œAlwaysā€ or
ā€œOftenā€ used.
Feature
     Devotion
       Text
Placing emphasis on
features instead of
 overall outcome
http://martinfowler.com/bliki/FeatureDevotion.html
t bu yer
        imp   atien
A s an                 y se arch
       t to  refi ne m
I wan                 dw  hat
     that  I ca n fin
 So
     ant  qui  ckly
  Iw
As an impatient buyer
I want to reļ¬ne my search
So that I can ļ¬nd what I want quickly
Feature: Advanced Search
As an impatient buyer
I want to reļ¬ne my search
So that I can ļ¬nd what I want quickly
token for
conversation
Gherkin
Scenario: title
Given [Context]
When [Action]
Then [Expected Outcome]
Scenario: title
Given [Context]
And [More Context]
When [Action]
And [Other Action]
Then [Expected Outcome]
But [Unexpected Outcome]
Scenario: search by director
Given the store has movies directed
by ā€œSteven Spielbergā€
When I search for ā€œSteven Spielbergā€
Then I should see all of the movies
directed by ā€œSteven Spielbergā€
Scenario: no results
Given the store has no movies
directed by ā€œSteven Spielbergā€
When I search for ā€œSteven Spielbergā€
Then I should see ā€œSorry, but no
movies were foundā€
Advanced
 Gherkin
Scenario: search by director
  Given movies directed by "Steven Spielberg" are
   in stock
  When I search for "Spielberg" under "Director"
  Then I the search results should be "E.T., and Jaws"
Step Tables
Scenario: search by director
  Given the following movies are in stock:
    | Title            | Director          | Year   |
    | Jaws             | Steven Spielberg | 1975    |
    | Star Wars        | George Lucas      | 1975   |
    | Dawn of the Dead | George Romero     | 1978   |
    | E.T.             | Steven Spielberg | 1982    |
  When I search for "Spielberg" under "Director"
  Then I the search results should be "E.T., and    Jaws"
Step Tables
Scenario: search by director
  Given the following movies are in stock:
    | Title            | Director          | Year   |
    | Jaws             | Steven Spielberg | 1975    |
    | Star Wars        | George Lucas      | 1975   |
    | Dawn of the Dead | George Romero     | 1978   |
    | E.T.             | Steven Spielberg | 1982    |
  When I search for "Spielberg" under "Director"
  Then I should see the following table:
    | Title      | Director         | Year |
    | Jaws       | Steven Spielberg | 1975 |
    | E.T.       | Steven Spielberg | 1982 |
Scenario: search by director
  Given the following movies are in stock:
    | Title            | Director          | Year   |
    | Jaws             | Steven Spielberg | 1975    |
    | Star Wars        | George Lucas      | 1975   |
    | Dawn of the Dead | George Romero     | 1978   |
    | E.T.             | Steven Spielberg | 1982    |
  When I search for "Spielberg" under "Director"
  Then I the search results should be "E.T., and    Jaws"
Scenario: search by director
  Given the following movies are in stock:
    | Title            | Director          | Year   |
    | Jaws             | Steven Spielberg | 1975    |
    | Star Wars        | George Lucas      | 1975   |
    | Dawn of the Dead | George Romero     | 1978   |
    | E.T.             | Steven Spielberg | 1982    |
  When I search for "Spielberg" under "Director"
  Then I the search results should be "E.T., and    Jaws"

                I only want to change
                the search query and
                    results part...
Scenario Outlines
Scenario Outline: search by director
  Given the following movies are in stock:
    | Title            | Director          | Year |
    | Jaws             | Steven Spielberg | 1975 |
    | Star Wars        | George Lucas      | 1975 |
    | Dawn of the Dead | George Romero     | 1978 |
    | E.T.             | Steven Spielberg | 1982 |
  When I search for "<Director Query>" under "Director"
  Then I the search results should be "<Search Results>"

  Examples:
    | Director Query | Search Results              |
    | Steve          | E.T., Jaws                  |
    | George         | Dawn of the Dead, Star Wars |
    | Lucas          | Star Wars                   |
Scenario Outlines
Scenario Outline: search by director
  Given the following movies are in stock:
    | Title            | Director          | Year |
    | Jaws             | Steven Spielberg | 1975 |
    | Star Wars        | George Lucas      | 1975 |
    | Dawn of the Dead | George Romero     | 1978 |
    | E.T.             | Steven Spielberg | 1982 |
  When I search for "<Director Query>" under "Director"
  Then I the search results should be "<Search Results>"

  Examples:
    | Director Query | Search Results              |
    | Steve          | E.T., Jaws                  |
    | George         | Dawn of the Dead, Star Wars |
    | Lucas          | Star Wars                   |
Background
Feature: Account Profile

  Scenario: change password success
    Given I'm logged in
    ...

  Scenario: update contact info
    Given I'm logged in
    ...
Background
Feature: Account Profile

  Background:
    Given I'm logged in

  Scenario: change password success
    ...

  Scenario: update contact info
    ...
Multi-Line String
      Steps
Scenario: register successfully
  Given I am on on the registration page
  When I sign up as "Jojo Binks"
  Then I should receive the following email:
  """
  Thanks for signing up Jojo!

 Important information about here.
 """
# language: ja
        :




  2

Ā Ā                             : 2
           <       1>
Ā Ā Ā Ā        <       2>
Ā Ā Ā Ā        <            >
Ā Ā Ā Ā            <        >

Ā Ā     :
Ā Ā Ā Ā |     1 |           2 |         |          |
Ā Ā Ā Ā | 20       | 30         | add       | 50       |
Ā Ā Ā Ā | 2        | 5          | add       | 7        |
Ā Ā Ā Ā | 0        | 40         | add       | 40       |
So now what?
uyer
           patient b
As an im ine my search
           ref
I want to       find wha
                          t
           can
 So that I
               kly
 Iw ant quic
uyer
           patient b
As an im ine my search
           ref
I want to       find wha
                          t
           can
 So that I
               kly
 Iw ant quic
patient b
                     uyer
As an im ine my search
                              Given...
I want to
           ref
                find wha
                          t   When...
 So that I
 Iw
           can
    ant quic
               kly            Then...
patient b
                     uyer
As an im ine my search
                              Given...
I want to
           ref
                find wha
                          t   When...
 So that I
 Iw
           can
    ant quic
               kly            Then...
patient b
                     uyer
As an im ine my search
                              Given...
I want to
           ref
                find wha
                          t   When...
 So that I
 Iw
           can
    ant quic
               kly            Then...
Automating
 Gherkin
project_root/
|
`-- features
project_root/
|
`-- features
    |-- awesomeness.feature
    |-- greatest_ever.feature
project_root/
|
`-- features
    |-- awesomeness.feature
    |-- greatest_ever.feature
    `-- support
        |-- env.rb
        `-- other_helpers.rb
project_root/
|
`-- features
    |-- awesomeness.feature
    |-- greatest_ever.feature
    `-- support
        |-- env.rb
        `-- other_helpers.rb
    |-- step_definitions
    |   |-- domain_concept_A.rb
    |   `-- domain_concept_B.rb
Step

Given a widget
Step         Deļ¬nition

                 Given /^a widget$/ do
Given a widget     #codes go here
                 end
When /^I search by director for "([^"]*)"$/ do |director|
end
Regexp Capture -> Yielded Variable


When /^I search by director for "([^"]*)"$/ do |director|
end
When /^I search by director for "([^"]*)"$/ do |director|
Ā Ā visit advanced_search_path
Ā Ā fill_in "By Director", :with => director
Ā Ā click_button "Search"
end



               Webrat, Webdriver, Watir, etc..
Not Just for Ruby
When /^I search by director for "([^"]*)"$/ do |director|
end




[Given(@"^I search by director for "([^"]*)"$")]
public void searchDirector(String director) {
}



    http://wiki.github.com/richardlawrence/Cuke4Nuke/
Gherkin
Gherkin   Ragel
Gherkin     Ragel



C, C++, Ruby, Java, .net, etc,
Gherkin         Ragel



C, C++, Ruby, Java, .net, etc,
      http://specļ¬‚ow.org/
http://wiki.github.com/aslakhellesoy/cuke4duke/
When /^I search by director for "([^"]*)"$/ do |director|
end


@When("^I search by director for "([^"]*)"$")
public void searchDirector(String director) {
}


When("^I search by director for "([^"]*)"$"{ String d ->
}



(When #"^I search by director for "([^"]*)"$"
Ā Ā (fn [director] ))




When("^I search by director for "([^"]*)"$"{ d: String =>
}
Uhh... this just seems
like more work for me.
Scenario Outline: search by director
    Given the following movies are in stock:
      | Title            | Director          | Year |
      | Jaws             | Steven Spielberg | 1975 |
      | Star Wars        | George Lucas      | 1975 |
      | Dawn of the Dead | George Romero     | 1978 |
      | E.T.             | Steven Spielberg | 1982 |
    When I search for "<Director Query>" under "Director"
    Then I the search results should be "<Search Results>"

    Examples:
      | Director Query   |   Search Results              |
      | Steve            |   E.T., Jaws                  |
      | George           |   Dawn of the Dead, Star Wars |
      | Zombie guy       |   Dawn of the Dead            |
      | Lucas            |   Star Wars                   |

  Scenario: search by director on a full moon
    Given that it is a full moon
    ...
Scenario Outline: search by director
    Given the following movies are in stock:
      | Title            | Director          | Year |
      | Jaws             | Steven Spielberg | 1975 |
      | Star Wars        | George Lucas      | 1975 |
      | Dawn of the Dead | George Romero     | 1978 |
      | E.T.             | Steven Spielberg | 1982 |
    When I search for "<Director Query>" under "Director"
    Then I the search results should be "<Search Results>"

    Examples:
      | Director Query   |   Search Results              |
      | Steve            |   E.T., Jaws                  |
      | George           |   Dawn of the Dead, Star Wars |
      | Zombie guy       |   Dawn of the Dead            |
      | Lucas            |   Star Wars                   |

  Scenario: search by director on a full moon
    Given that it is a full moon
    ...
You know where to begin and end.




                             Yo
You know when you broke something.
Outside-In
Model
Controller
  Model
View
Controller
  Model
UI/UX
  View
Controller
  Model
UI/UX
  View
Controller
  Model
Write Scenarios
Steps are pending
Write Step Deļ¬nition
Go Down A Gear
RSpec, xUnit, etc
Write Unit Test
Make Unit Test Pass
REFACTOR!!
Where Are we?
Continue until...
REFACTOR
   and
 REPEAT
Next set of slides stolen from
Aslak HellesĆøy, creator of
     http://www.slideshare.net/aslak.hellesoy/cuke4duke-javazone-2009
Feature: code-breaker submits guess
  In order to make time pass when I'm alone
  As a player
  I want to play the against a machine

  Scenario: all correct
    Given the secret code is "r g y c"
    When I guess "r g y c"
    Then the mark should be "bbbb"
$ gem install cucumber
$ cucumber features
<repositories>
  <repository>
    <id>cukes</id>
    <url>http://cukes.info/maven</url>
  </repository>
</repositories>

<pluginRepositories>
  <pluginRepository>
    <id>cukes</id>
    <url>http://cukes.info/maven</url>
  </pluginRepository>
</pluginRepositories>
<dependencies>
  <dependency>
    <groupId>cuke4duke</groupId>
    <artifactId>cuke4duke</artifactId>
    <version>0.3.0</version>
  </dependency>
  <dependency>
    <groupId>org.picocontainer</groupId>
    <artifactId>picocontainer</artifactId>
    <version>2.8.3</version>
  </dependency>
</dependencies>
<plugin>
  <groupId>cuke4duke</groupId>
  <artifactId>cuke4duke-maven-plugin</artifactId>
  <configuration>
    <jvmArgs>
      <jvmArg>
         -Dcuke4duke.objectFactory=
        cuke4duke.internal.java.PicoFactory
      </jvmArg>
    </jvmArgs>
    <cucumberArgs>
      <cucumberArg>${basedir}/src/test/java</cucumberArg>
    </cucumberArgs>
    <gems>
      <gem>install cuke4duke --version x.y.x</gem>
    </gems>
  </configuration>
</plugin>
$ mvn integration-test 
  -Dcucumber.installGems=true
Feature: code-breaker submits guess
  In order to make time pass when I'm alone
  As a player
  I want to play the against a machine

 Scenario: all correct                # features/c..s.feature:6
   Given the secret code is "r g y c" # features/c..s.feature:7
   When I guess "r g y c"             # features/c..s.feature:8
   Then the mark should be "bbbb"     # features/c..s.feature:9

1 scenario (1 undefined)
3 steps (3 undefined)
0m0.076s
You can implement step definitions for undefined steps with these
snippets:

@Given("^the secret code is "([^"]*)"$")
@Pending
public void theSecretCodeIsRGYC_(String arg1) {
}

@When("^I guess "([^"]*)"$")
@Pending
public void iGuessRGYC_(String arg1) {
}

@Then("^the mark should be "([^"]*)"$")
@Pending
public void theMarkShouldBeBbbb_(String arg1) {
}
package codebreaker;
import cuke4duke.*;

public class CodeBreakerSteps {
    @Given("^the secret code is "([^"]*)"$")
    @Pending
    public void theSecretCodeIs(String code) {
    }

    @When("^I guess "([^"]*)"$")
    @Pending
    public void iGuess(String guess) {
    }

    @Then("^the mark should be "([^"]*)"$")
    @Pending
    public void theMarkShouldBe(String mark) {
    }
}
$ mvn integration-test


Feature: code-breaker submits guess
  In order to make time pass when I'm alone
  As a player
  I want to play the against a machine

 Scenario: all correct                  # features/c..s.feature:6
   Given the secret code is "r g y c"   # public void theS..(..)
     TODO (Cucumber::Pending)
     f../c..s.feature:7:in `Given the   secret code is "r g y c"'
   When I guess "r g y c"               # public void iGue..(..)
   Then the mark should be "bbbb"       # public void theM..(..)

1 scenario (1 pending)
3 steps (2 skipped, 1 pending)
0m0.079s
Given the secret code is "r g y c"
# public void codebreaker.GameSteps
  .theSecretCodeIs(java.lang.String)
Given the secret code is "r g y c"
Given the secret code is "r g y c"


@Given("^the secret code is "([^"]*)"$")
public void theSecretCodeIs(String code) {

}
public class GameSteps {
    private Game game;

    @Given("^the secret code is "([^"]*)"$")
    public void theSecretCodeIs(String code) {
        game = new Game(code);
    }
}
Compilation failure

src/test/java/codebreaker/
CodeBreakerSteps.java:[6,12] cannot find symbol
symbol : class Game
location: class codebreaker.CodeBreakerSteps
package codebreaker;

public class Game {
    public Game(String code) {
    }
}
$ mvn integration-test


Feature: code-breaker submits guess
  In order to make time pass when I'm alone
  As a player
  I want to play the against a machine

 Scenario: all correct                # features/c..s.feature:6
   Given the secret code is "r g y c" # public void theS..(..)
   When I guess "r g y c"             # public void iGue..(..)
     TODO (Cucumber::Pending)
     f../c..s.feature:8:in `When I guess "r g y c"'
   Then the mark should be "bbbb"     # public void theM..(..)

1 scenario (1 pending)
3 steps (1 skipped, 1 pending, 1 passed)
0m0.112s
$ mvn integration-test


Feature: code-breaker submits guess
  In order to make time pass when I'm alone
  As a player
  I want to play the against a machine

 Scenario: all correct                # features/c..s.feature:6
   Given the secret code is "r g y c" # public void theS..(..)
   When I guess "r g y c"             # public void iGue..(..)
   Then the mark should be "bbbb"     # public void theM..(..)

1 scenario (1 passed)
3 steps (3 passed)
0m0.121s
Scenario: all correct
  Given the secret code is "r g y c"
  When I guess "r g y c"
  Then the mark should be "bbbb"

Scenario: 2 wrong pos, 2 correct
  Given the secret code is "r g y c"
  When I guess "r g c y"
  Then the mark should be "bbww"
Scenario: all correct                # features/c..s.feature:6
   Given the secret code is "r g y c" # public void theS..(..)
   When I guess "r g y c"             # public void iGue..(..)
   Then the mark should be "bbbb"     # public void theM..(..)

 Scenario: all correct                # features/c..s.feature:6
   Given the secret code is "r g y c" # public void theS..(..)
   When I guess "r g y c"             # public void iGue..(..)
   Then the mark should be "bbbb"     # public void theM..(..)
     org.junit.ComparisonFailure: expected:<bb[bb]> but
         was:<bb[ww]> (NativeException)
     codebreaker/CodeBreakerSteps.java:20:in `theMarkShouldBe'
     features/codebreaker_submits_guess.feature:14:in `Then
         the mark should be "bbww"'



1 scenario (1 failed, 1 passed)
3 steps (1 failed, 3 passed)
0m0.121s
Scenario: all correct
  Given the secret code is "r g y c"
  When I guess "r g y c"
  Then the mark should be "bbbb"

Scenario: 2 wrong pos, 2 correct
  Given the secret code is "r g y c"
  When I guess "r g c y"
  Then the mark should be "bbww"
Scenario Outline: submit guess
  Given the secret code is "<code>"
  When I guess "<guess>"
  Then the mark should be "<mark>"

Examples:
  | code        |   guess       |   mark   |
  | r g y   c   |   r g y   c   |   bbbb   |
  | r g y   c   |   r g c   y   |   bbww   |
  | r g y   c   |   y r g   c   |   bwww   |
  | r g y   c   |   c r g   y   |   wwww   |
More Tricks
Tags
@store @lucene
Feature: Advanced Search
  ...

 @wip
 Scenario: search by director
   ...

 @proposed @pending_ui
 Scenario: items not carried
   ...

 @nightly
 Scenario: long running
   ...

 @third_party
 Scenario: search Amazon
   ...
@store @lucene
Feature: Advanced Search
  ...

 @wip
 Scenario: search by director
   ...

 @proposed @pending_ui
 Scenario: items not carried
   ...

 @nightly
 Scenario: long running
   ...

 @third_party
 Scenario: search Amazon
   ...
@store @lucene
Feature: Advanced Search
  ...

 @wip
           Tag Exclusion
 Scenario: search by director
   ...

 @proposed @pending_ui
       cucumber --tags ~@proposed
 Scenario: items not carried
   ...

 @nightly
 Scenario: long running
   ...

 @third_party
 Scenario: search Amazon
   ...
@store @lucene
Feature: Advanced Search
  ...

 @wip
 Scenario: search by director
   ...

 @proposed @pending_ui
 Scenario: items not carried
   ...

 @nightly
 Scenario: long running
   ...

 @third_party
 Scenario: search Amazon
   ...
@store @lucene
Feature: Advanced Search
  ...

 @wip
 Scenario: search by director
   ...

 @proposed @pending_ui
 Scenario: items --tags @wip:2
      cucumber not carried       --wip
   ...

 @nightly
 Scenario: long running
   ...

 @third_party
 Scenario: search Amazon
   ...
@store @lucene
Feature: Advanced Search
  ...

 @wip           Limit scenarios in ļ¬‚ow
 Scenario: search by director
   ...

 @proposed @pending_ui
 Scenario: items --tags @wip:2
      cucumber not carried       --wip
   ...

 @nightly
 Scenario: long running
   ...

 @third_party
 Scenario: search Amazon
   ...
@store @lucene
Feature: Advanced Search
  ...

 @wip           Limit scenarios in ļ¬‚ow
 Scenario: search by director
   ...

 @proposed @pending_ui
 Scenario: items --tags @wip:2
      cucumber not carried       --wip
   ...

 @nightly
           Expect failure - Success == Failure
 Scenario: long running
   ...

 @third_party
 Scenario: search Amazon
   ...
Hooks
Before do
end

After do |scenario|
end

World do
end

World(MyModule)
World(HerModule)
Tagged Hooks
Before('@im_special', '@me_too') do
  @icecream = true
end

@me_too             Feature: Sit
Feature: Lorem        @im_special
  Scenario: Ipsum     Scenario: Amet
  Scenario: Dolor     Scenario: Consec
Acceptance Tests
       ==
  End-to-End?
Slow




Fast
Slow   Integrated




Fast    Isolated
Slow   Integrated




Fast    Isolated
Slow              Integrated



       HtmlUnit
              V8

Fast               Isolated
Slow              Integrated



       HtmlUnit
              V8

Fast               Isolated
What about me?
patient b
                     uyer
As an im ine my search
                              Given...
I want to
           ref
                find wha
                          t   When...
 So that I
 Iw
           can
    ant quic
               kly            Then...
patient b
                     uyer
As an im ine my search
                              Given...
I want to
           ref
                find wha
                          t   When...
 So that I
 Iw
           can
    ant quic
               kly            Then...
patient b
                     uyer
As an im ine my search
                              Given...
I want to
           ref
                find wha
                          t   When...
 So that I
 Iw
           can
    ant quic
               kly            Then...
patient b
                     uyer
As an im ine my search
                              Given...
I want to
           ref
                find wha
                          t   When...
 So that I
 Iw
           can
    ant quic
               kly            Then...
patient b
                     uyer
As an im ine my search
                              Given...
I want to
           ref
                find wha
                          t   When...
 So that I
 Iw
           can
    ant quic
               kly            Then...
Dead
                         er
              t ient buy
As  an impa         m y search
I want   to refine          t
                  find wha
 So  that I can
                   y
 I wan  t quickl



          D
       PR
Dead                                     Living
                                 Feature: Advanced Search
                                   As an impatient buyer
                                   I want to refine my search
                                   So that I can find what I want quickly
                                 Scenario Outline: search by director
                         er        Given the following movies are in stock:
              t ient buy
    an impa
                                     | Title            | Director          | Year |
As                  m y search       | Jaws             | Steven Spielberg | 1975 |

I want   to refine          t
                                     | Star Wars        | George Lucas      | 1975 |

                  find wha
                                     | Dawn of the Dead | George Romero     | 1978 |

     that I can
                                     | E.T.             | Steven Spielberg | 1982 |
 So                y               When I search for "<Director Query>" under "Director"

 I wan  t quickl                   Then I the search results should be "<Search Results>"

                                   Examples:
                                     | Director Query | Search Results              |
                                     | Steve          | E.T., Jaws                  |
                                     | George         | Dawn of the Dead, Star Wars |

          D                          | Lucas          | Star Wars                   |

       PR
Gherkin
Subtleties
Feature: Advanced Search
  As an impatient buyer
  I want to refine my search
  So that I can find what I want quickly
Feature: Advanced Search
  As an impatient buyer
  I want to refine my search
  So that I can find what I want quickly


  Scenario: search by director
    Given movies directed by "Steven Spielberg" are in stock
    When I search by director for "Spielberg"
    Then I should see all of the movies directed by "Steven Spielberg"
Feature: Advanced Search
  As an impatient buyer
  I want to refine my search
  So that I can find what I want quickly
      Declarative
 Scenario: search by director
   Given movies directed by "Steven Spielberg" are in stock
   When I search by director for "Spielberg"
   Then I should see all of the movies directed by "Steven Spielberg"
Feature: Advanced Search
  As an impatient buyer
  I want to refine my search
  So that I can find what I want quickly
      Imperative
 Scenario: search by director
   Given movies directed by "Steven Spielberg" are in stock
   And I am on the "Advanced Search" page
   When I fill in "Spielberg" for "Director"
   And press "Submit"
   Then I should see all of the movies directed by "Steven Spielberg"
Feature: Advanced Search
  As an impatient buyer
  I want to refine my search
  So that I can find what I want quickly
      Imperative
 Scenario: search by director
   Given movies directed by "Steven Spielberg" are in stock
   And I am on the "Advanced Search" page
   When I fill in "Spielberg" for "Director"
   And press "Submit"
   Then I should see all of the movies directed by "Steven Spielberg"



                         I like it! I actually know
                          how a user can use it!
Balance
Abstraction
Scenario: successful login
  Given I'm on the login page
  When I fill in "jimmy" for "Login"
  And fill in "password" for "Password"
  And click "Login"
  Then I should see "Welcome back jimmy!"
Scenario: change password success
Scenario: change password success
  Given I'm on the login page
  When I fill in "jimmy" for "Login"
  And fill in "password" for "Password"
  And click "Login"
  Then I should see "Welcome back jimmy!"
Scenario: change password success
  Given I'm on the login page
  When I fill in "jimmy" for "Login"
  And fill in "password" for "Password"
  And click "Login"
  Then I should see "Welcome back jimmy!"
  When I click "Change Password"
  And fill in the following
    | Old Password | password |
    | New Password | brand-new |
    | Confirmation | brand-new |
  And click "Change Password"
  Then I should see "Your password has been changed."
Scenario: change password success
  Given I'm on the login page
  When I fill in "jimmy" for "Login"
  And fill in "password" for "Password"
  And click "Login"
  Then I should see "Welcome back jimmy!"
  When I click "Change Password"
                     Incidental Details
  And fill in the following
    | Old Password | password |
    | New Password | brand-new |
    | Confirmation | brand-new |
  And click "Change Password"
  Then I should see "Your password has been changed."
Scenario: change password success
  Given I'm logged in
  When I click "Change Password"   Hide the noise!
  And fill in the following
    | Old Password | password |
    | New Password | brand-new |
    | Confirmation | brand-new |
  And click "Change Password"
  Then I should see "Your password has been changed."
Resources
                      http://cukes.info
      http://wiki.github.com/aslakhellesoy/cuke4duke/
          http://blog.dannorth.net/whats-in-a-story/
http://blog.josephwilk.net/ruby/rocket-fuelled-cucumbers.html
       http://benmabey.com/2008/05/19/imperative-vs-
           declarative-scenarios-in-user-stories.html
Thanks!
  BenMabey.com
github.com/bmabey
 Twitter: bmabey

More Related Content

More from Ben Mabey

Github flow
Github flowGithub flow
Github flowBen Mabey
Ā 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with CucumberBen Mabey
Ā 
Outside-In Development With Cucumber
Outside-In Development With CucumberOutside-In Development With Cucumber
Outside-In Development With CucumberBen Mabey
Ā 
Disconnecting the Database with ActiveRecord
Disconnecting the Database with ActiveRecordDisconnecting the Database with ActiveRecord
Disconnecting the Database with ActiveRecordBen Mabey
Ā 
SVD and the Netflix Dataset
SVD and the Netflix DatasetSVD and the Netflix Dataset
SVD and the Netflix DatasetBen Mabey
Ā 
The WHY behind TDD/BDD and the HOW with RSpec
The WHY behind TDD/BDD and the HOW with RSpecThe WHY behind TDD/BDD and the HOW with RSpec
The WHY behind TDD/BDD and the HOW with RSpecBen Mabey
Ā 

More from Ben Mabey (6)

Github flow
Github flowGithub flow
Github flow
Ā 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with Cucumber
Ā 
Outside-In Development With Cucumber
Outside-In Development With CucumberOutside-In Development With Cucumber
Outside-In Development With Cucumber
Ā 
Disconnecting the Database with ActiveRecord
Disconnecting the Database with ActiveRecordDisconnecting the Database with ActiveRecord
Disconnecting the Database with ActiveRecord
Ā 
SVD and the Netflix Dataset
SVD and the Netflix DatasetSVD and the Netflix Dataset
SVD and the Netflix Dataset
Ā 
The WHY behind TDD/BDD and the HOW with RSpec
The WHY behind TDD/BDD and the HOW with RSpecThe WHY behind TDD/BDD and the HOW with RSpec
The WHY behind TDD/BDD and the HOW with RSpec
Ā 

Recently uploaded

Amil baba in Pakistan amil baba Karachi amil baba in pakistan amil baba in la...
Amil baba in Pakistan amil baba Karachi amil baba in pakistan amil baba in la...Amil baba in Pakistan amil baba Karachi amil baba in pakistan amil baba in la...
Amil baba in Pakistan amil baba Karachi amil baba in pakistan amil baba in la...Amil Baba Company
Ā 
Kolkata Call Girl Bagbazar šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Bagbazar šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7Kolkata Call Girl Bagbazar šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Bagbazar šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7Riya Pathan
Ā 
Hot Call Girls In Goa 7028418221 Call Girls In Vagator Beach EsCoRtS
Hot Call Girls In Goa 7028418221 Call Girls In Vagator Beach EsCoRtSHot Call Girls In Goa 7028418221 Call Girls In Vagator Beach EsCoRtS
Hot Call Girls In Goa 7028418221 Call Girls In Vagator Beach EsCoRtSApsara Of India
Ā 
ViP Call Girls In Udaipur 9602870969 Gulab Bagh Escorts SeRvIcE
ViP Call Girls In Udaipur 9602870969 Gulab Bagh Escorts SeRvIcEViP Call Girls In Udaipur 9602870969 Gulab Bagh Escorts SeRvIcE
ViP Call Girls In Udaipur 9602870969 Gulab Bagh Escorts SeRvIcEApsara Of India
Ā 
QUIZ BOLLYWOOD ( weekly quiz ) - SJU quizzers
QUIZ BOLLYWOOD ( weekly quiz ) - SJU quizzersQUIZ BOLLYWOOD ( weekly quiz ) - SJU quizzers
QUIZ BOLLYWOOD ( weekly quiz ) - SJU quizzersSJU Quizzers
Ā 
5* Hotel Call Girls In Goa 7028418221 Call Girls In North Goa Escort Services
5* Hotel Call Girls In Goa 7028418221 Call Girls In North Goa Escort Services5* Hotel Call Girls In Goa 7028418221 Call Girls In North Goa Escort Services
5* Hotel Call Girls In Goa 7028418221 Call Girls In North Goa Escort ServicesApsara Of India
Ā 
Authentic No 1 Amil Baba In Pakistan Authentic No 1 Amil Baba In Karachi No 1...
Authentic No 1 Amil Baba In Pakistan Authentic No 1 Amil Baba In Karachi No 1...Authentic No 1 Amil Baba In Pakistan Authentic No 1 Amil Baba In Karachi No 1...
Authentic No 1 Amil Baba In Pakistan Authentic No 1 Amil Baba In Karachi No 1...First NO1 World Amil baba in Faisalabad
Ā 
VIP Call Girls In Goa 7028418221 Call Girls In Baga Beach Escorts Service
VIP Call Girls In Goa 7028418221 Call Girls In Baga Beach Escorts ServiceVIP Call Girls In Goa 7028418221 Call Girls In Baga Beach Escorts Service
VIP Call Girls In Goa 7028418221 Call Girls In Baga Beach Escorts ServiceApsara Of India
Ā 
Call Girl Price Andheri WhatsApp:+91-9833363713
Call Girl Price Andheri WhatsApp:+91-9833363713Call Girl Price Andheri WhatsApp:+91-9833363713
Call Girl Price Andheri WhatsApp:+91-9833363713Sonam Pathan
Ā 
Kolkata Call Girl Airport Kolkata šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Airport Kolkata šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7Kolkata Call Girl Airport Kolkata šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Airport Kolkata šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7Riya Pathan
Ā 
Fun Call Girls In Goa 7028418221 Escort Service In Morjim Beach Call Girl
Fun Call Girls In Goa 7028418221 Escort Service In Morjim Beach Call GirlFun Call Girls In Goa 7028418221 Escort Service In Morjim Beach Call Girl
Fun Call Girls In Goa 7028418221 Escort Service In Morjim Beach Call GirlApsara Of India
Ā 
Call Girls Somajiguda Sarani 7001305949 all area service COD available Any Time
Call Girls Somajiguda Sarani 7001305949 all area service COD available Any TimeCall Girls Somajiguda Sarani 7001305949 all area service COD available Any Time
Call Girls Somajiguda Sarani 7001305949 all area service COD available Any Timedelhimodelshub1
Ā 
8377087607 Full Enjoy @24/7 Call Girls in Patel Nagar Delhi NCR
8377087607 Full Enjoy @24/7 Call Girls in Patel Nagar Delhi NCR8377087607 Full Enjoy @24/7 Call Girls in Patel Nagar Delhi NCR
8377087607 Full Enjoy @24/7 Call Girls in Patel Nagar Delhi NCRdollysharma2066
Ā 
Call US '' 8377087607'' !! Call Girls In Model Town Metro (Delhi NCR)
Call US '' 8377087607'' !! Call Girls In Model Town Metro (Delhi NCR)Call US '' 8377087607'' !! Call Girls In Model Town Metro (Delhi NCR)
Call US '' 8377087607'' !! Call Girls In Model Town Metro (Delhi NCR)dollysharma2066
Ā 
Call Girls Jodhpur Park - [ Cash on Delivery ] Contact 8250192130 Escorts Ser...
Call Girls Jodhpur Park - [ Cash on Delivery ] Contact 8250192130 Escorts Ser...Call Girls Jodhpur Park - [ Cash on Delivery ] Contact 8250192130 Escorts Ser...
Call Girls Jodhpur Park - [ Cash on Delivery ] Contact 8250192130 Escorts Ser...Riya Pathan
Ā 
Models Call Girls Hridaypur | 8250192130 At Low Cost Cash Payment Booking
Models Call Girls Hridaypur | 8250192130 At Low Cost Cash Payment BookingModels Call Girls Hridaypur | 8250192130 At Low Cost Cash Payment Booking
Models Call Girls Hridaypur | 8250192130 At Low Cost Cash Payment Bookinganamikaraghav4
Ā 
Real NO1 Amil baba in Faisalabad Kala jadu in faisalabad Aamil baba Faisalaba...
Real NO1 Amil baba in Faisalabad Kala jadu in faisalabad Aamil baba Faisalaba...Real NO1 Amil baba in Faisalabad Kala jadu in faisalabad Aamil baba Faisalaba...
Real NO1 Amil baba in Faisalabad Kala jadu in faisalabad Aamil baba Faisalaba...Amil Baba Company
Ā 
NO1 WorldWide Amil baba in pakistan Amil Baba in Karachi Black Magic Islamaba...
NO1 WorldWide Amil baba in pakistan Amil Baba in Karachi Black Magic Islamaba...NO1 WorldWide Amil baba in pakistan Amil Baba in Karachi Black Magic Islamaba...
NO1 WorldWide Amil baba in pakistan Amil Baba in Karachi Black Magic Islamaba...Amil baba
Ā 
Kolkata Call Girl Howrah šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Howrah šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7Kolkata Call Girl Howrah šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Howrah šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7Riya Pathan
Ā 
Gripping Adult Web Series You Can't Afford to Miss
Gripping Adult Web Series You Can't Afford to MissGripping Adult Web Series You Can't Afford to Miss
Gripping Adult Web Series You Can't Afford to Missget joys
Ā 

Recently uploaded (20)

Amil baba in Pakistan amil baba Karachi amil baba in pakistan amil baba in la...
Amil baba in Pakistan amil baba Karachi amil baba in pakistan amil baba in la...Amil baba in Pakistan amil baba Karachi amil baba in pakistan amil baba in la...
Amil baba in Pakistan amil baba Karachi amil baba in pakistan amil baba in la...
Ā 
Kolkata Call Girl Bagbazar šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Bagbazar šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7Kolkata Call Girl Bagbazar šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Bagbazar šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Ā 
Hot Call Girls In Goa 7028418221 Call Girls In Vagator Beach EsCoRtS
Hot Call Girls In Goa 7028418221 Call Girls In Vagator Beach EsCoRtSHot Call Girls In Goa 7028418221 Call Girls In Vagator Beach EsCoRtS
Hot Call Girls In Goa 7028418221 Call Girls In Vagator Beach EsCoRtS
Ā 
ViP Call Girls In Udaipur 9602870969 Gulab Bagh Escorts SeRvIcE
ViP Call Girls In Udaipur 9602870969 Gulab Bagh Escorts SeRvIcEViP Call Girls In Udaipur 9602870969 Gulab Bagh Escorts SeRvIcE
ViP Call Girls In Udaipur 9602870969 Gulab Bagh Escorts SeRvIcE
Ā 
QUIZ BOLLYWOOD ( weekly quiz ) - SJU quizzers
QUIZ BOLLYWOOD ( weekly quiz ) - SJU quizzersQUIZ BOLLYWOOD ( weekly quiz ) - SJU quizzers
QUIZ BOLLYWOOD ( weekly quiz ) - SJU quizzers
Ā 
5* Hotel Call Girls In Goa 7028418221 Call Girls In North Goa Escort Services
5* Hotel Call Girls In Goa 7028418221 Call Girls In North Goa Escort Services5* Hotel Call Girls In Goa 7028418221 Call Girls In North Goa Escort Services
5* Hotel Call Girls In Goa 7028418221 Call Girls In North Goa Escort Services
Ā 
Authentic No 1 Amil Baba In Pakistan Authentic No 1 Amil Baba In Karachi No 1...
Authentic No 1 Amil Baba In Pakistan Authentic No 1 Amil Baba In Karachi No 1...Authentic No 1 Amil Baba In Pakistan Authentic No 1 Amil Baba In Karachi No 1...
Authentic No 1 Amil Baba In Pakistan Authentic No 1 Amil Baba In Karachi No 1...
Ā 
VIP Call Girls In Goa 7028418221 Call Girls In Baga Beach Escorts Service
VIP Call Girls In Goa 7028418221 Call Girls In Baga Beach Escorts ServiceVIP Call Girls In Goa 7028418221 Call Girls In Baga Beach Escorts Service
VIP Call Girls In Goa 7028418221 Call Girls In Baga Beach Escorts Service
Ā 
Call Girl Price Andheri WhatsApp:+91-9833363713
Call Girl Price Andheri WhatsApp:+91-9833363713Call Girl Price Andheri WhatsApp:+91-9833363713
Call Girl Price Andheri WhatsApp:+91-9833363713
Ā 
Kolkata Call Girl Airport Kolkata šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Airport Kolkata šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7Kolkata Call Girl Airport Kolkata šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Airport Kolkata šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Ā 
Fun Call Girls In Goa 7028418221 Escort Service In Morjim Beach Call Girl
Fun Call Girls In Goa 7028418221 Escort Service In Morjim Beach Call GirlFun Call Girls In Goa 7028418221 Escort Service In Morjim Beach Call Girl
Fun Call Girls In Goa 7028418221 Escort Service In Morjim Beach Call Girl
Ā 
Call Girls Somajiguda Sarani 7001305949 all area service COD available Any Time
Call Girls Somajiguda Sarani 7001305949 all area service COD available Any TimeCall Girls Somajiguda Sarani 7001305949 all area service COD available Any Time
Call Girls Somajiguda Sarani 7001305949 all area service COD available Any Time
Ā 
8377087607 Full Enjoy @24/7 Call Girls in Patel Nagar Delhi NCR
8377087607 Full Enjoy @24/7 Call Girls in Patel Nagar Delhi NCR8377087607 Full Enjoy @24/7 Call Girls in Patel Nagar Delhi NCR
8377087607 Full Enjoy @24/7 Call Girls in Patel Nagar Delhi NCR
Ā 
Call US '' 8377087607'' !! Call Girls In Model Town Metro (Delhi NCR)
Call US '' 8377087607'' !! Call Girls In Model Town Metro (Delhi NCR)Call US '' 8377087607'' !! Call Girls In Model Town Metro (Delhi NCR)
Call US '' 8377087607'' !! Call Girls In Model Town Metro (Delhi NCR)
Ā 
Call Girls Jodhpur Park - [ Cash on Delivery ] Contact 8250192130 Escorts Ser...
Call Girls Jodhpur Park - [ Cash on Delivery ] Contact 8250192130 Escorts Ser...Call Girls Jodhpur Park - [ Cash on Delivery ] Contact 8250192130 Escorts Ser...
Call Girls Jodhpur Park - [ Cash on Delivery ] Contact 8250192130 Escorts Ser...
Ā 
Models Call Girls Hridaypur | 8250192130 At Low Cost Cash Payment Booking
Models Call Girls Hridaypur | 8250192130 At Low Cost Cash Payment BookingModels Call Girls Hridaypur | 8250192130 At Low Cost Cash Payment Booking
Models Call Girls Hridaypur | 8250192130 At Low Cost Cash Payment Booking
Ā 
Real NO1 Amil baba in Faisalabad Kala jadu in faisalabad Aamil baba Faisalaba...
Real NO1 Amil baba in Faisalabad Kala jadu in faisalabad Aamil baba Faisalaba...Real NO1 Amil baba in Faisalabad Kala jadu in faisalabad Aamil baba Faisalaba...
Real NO1 Amil baba in Faisalabad Kala jadu in faisalabad Aamil baba Faisalaba...
Ā 
NO1 WorldWide Amil baba in pakistan Amil Baba in Karachi Black Magic Islamaba...
NO1 WorldWide Amil baba in pakistan Amil Baba in Karachi Black Magic Islamaba...NO1 WorldWide Amil baba in pakistan Amil Baba in Karachi Black Magic Islamaba...
NO1 WorldWide Amil baba in pakistan Amil Baba in Karachi Black Magic Islamaba...
Ā 
Kolkata Call Girl Howrah šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Howrah šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7Kolkata Call Girl Howrah šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Kolkata Call Girl Howrah šŸ‘‰ 8250192130 ā£ļøšŸ’Æ Available With Room 24Ɨ7
Ā 
Gripping Adult Web Series You Can't Afford to Miss
Gripping Adult Web Series You Can't Afford to MissGripping Adult Web Series You Can't Afford to Miss
Gripping Adult Web Series You Can't Afford to Miss
Ā 

Cucumber: Automating the Requirements Language You Already Speak

  • 1. Automating the Requirements Language You Already Speak Ben Mabey @bmabey
  • 2. Developer Tester Product Manager Designer/UX
  • 4. 56% of all bugs are introduced in requirements. (CHAOS Report)
  • 5. 45% of functionality is never used
  • 6. Only 20% makes up core functionality that is ā€œAlwaysā€ or ā€œOftenā€ used.
  • 7. Feature Devotion Text Placing emphasis on features instead of overall outcome http://martinfowler.com/bliki/FeatureDevotion.html
  • 8. t bu yer imp atien A s an y se arch t to refi ne m I wan dw hat that I ca n fin So ant qui ckly Iw
  • 9. As an impatient buyer I want to reļ¬ne my search So that I can ļ¬nd what I want quickly
  • 10. Feature: Advanced Search As an impatient buyer I want to reļ¬ne my search So that I can ļ¬nd what I want quickly
  • 13. Scenario: title Given [Context] When [Action] Then [Expected Outcome]
  • 14. Scenario: title Given [Context] And [More Context] When [Action] And [Other Action] Then [Expected Outcome] But [Unexpected Outcome]
  • 15. Scenario: search by director Given the store has movies directed by ā€œSteven Spielbergā€ When I search for ā€œSteven Spielbergā€ Then I should see all of the movies directed by ā€œSteven Spielbergā€
  • 16. Scenario: no results Given the store has no movies directed by ā€œSteven Spielbergā€ When I search for ā€œSteven Spielbergā€ Then I should see ā€œSorry, but no movies were foundā€
  • 18. Scenario: search by director Given movies directed by "Steven Spielberg" are in stock When I search for "Spielberg" under "Director" Then I the search results should be "E.T., and Jaws"
  • 19.
  • 20. Step Tables Scenario: search by director Given the following movies are in stock: | Title | Director | Year | | Jaws | Steven Spielberg | 1975 | | Star Wars | George Lucas | 1975 | | Dawn of the Dead | George Romero | 1978 | | E.T. | Steven Spielberg | 1982 | When I search for "Spielberg" under "Director" Then I the search results should be "E.T., and Jaws"
  • 21. Step Tables Scenario: search by director Given the following movies are in stock: | Title | Director | Year | | Jaws | Steven Spielberg | 1975 | | Star Wars | George Lucas | 1975 | | Dawn of the Dead | George Romero | 1978 | | E.T. | Steven Spielberg | 1982 | When I search for "Spielberg" under "Director" Then I should see the following table: | Title | Director | Year | | Jaws | Steven Spielberg | 1975 | | E.T. | Steven Spielberg | 1982 |
  • 22. Scenario: search by director Given the following movies are in stock: | Title | Director | Year | | Jaws | Steven Spielberg | 1975 | | Star Wars | George Lucas | 1975 | | Dawn of the Dead | George Romero | 1978 | | E.T. | Steven Spielberg | 1982 | When I search for "Spielberg" under "Director" Then I the search results should be "E.T., and Jaws"
  • 23. Scenario: search by director Given the following movies are in stock: | Title | Director | Year | | Jaws | Steven Spielberg | 1975 | | Star Wars | George Lucas | 1975 | | Dawn of the Dead | George Romero | 1978 | | E.T. | Steven Spielberg | 1982 | When I search for "Spielberg" under "Director" Then I the search results should be "E.T., and Jaws" I only want to change the search query and results part...
  • 24. Scenario Outlines Scenario Outline: search by director Given the following movies are in stock: | Title | Director | Year | | Jaws | Steven Spielberg | 1975 | | Star Wars | George Lucas | 1975 | | Dawn of the Dead | George Romero | 1978 | | E.T. | Steven Spielberg | 1982 | When I search for "<Director Query>" under "Director" Then I the search results should be "<Search Results>" Examples: | Director Query | Search Results | | Steve | E.T., Jaws | | George | Dawn of the Dead, Star Wars | | Lucas | Star Wars |
  • 25. Scenario Outlines Scenario Outline: search by director Given the following movies are in stock: | Title | Director | Year | | Jaws | Steven Spielberg | 1975 | | Star Wars | George Lucas | 1975 | | Dawn of the Dead | George Romero | 1978 | | E.T. | Steven Spielberg | 1982 | When I search for "<Director Query>" under "Director" Then I the search results should be "<Search Results>" Examples: | Director Query | Search Results | | Steve | E.T., Jaws | | George | Dawn of the Dead, Star Wars | | Lucas | Star Wars |
  • 26. Background Feature: Account Profile Scenario: change password success Given I'm logged in ... Scenario: update contact info Given I'm logged in ...
  • 27. Background Feature: Account Profile Background: Given I'm logged in Scenario: change password success ... Scenario: update contact info ...
  • 28. Multi-Line String Steps Scenario: register successfully Given I am on on the registration page When I sign up as "Jojo Binks" Then I should receive the following email: """ Thanks for signing up Jojo! Important information about here. """
  • 29. # language: ja : 2 Ā Ā  : 2 < 1> Ā Ā Ā Ā  < 2> Ā Ā Ā Ā  < > Ā Ā Ā Ā  < > Ā Ā  : Ā Ā Ā Ā | 1 | 2 | | | Ā Ā Ā Ā | 20 | 30 | add | 50 | Ā Ā Ā Ā | 2 | 5 | add | 7 | Ā Ā Ā Ā | 0 | 40 | add | 40 |
  • 30.
  • 32. uyer patient b As an im ine my search ref I want to find wha t can So that I kly Iw ant quic
  • 33. uyer patient b As an im ine my search ref I want to find wha t can So that I kly Iw ant quic
  • 34. patient b uyer As an im ine my search Given... I want to ref find wha t When... So that I Iw can ant quic kly Then...
  • 35. patient b uyer As an im ine my search Given... I want to ref find wha t When... So that I Iw can ant quic kly Then...
  • 36. patient b uyer As an im ine my search Given... I want to ref find wha t When... So that I Iw can ant quic kly Then...
  • 39. project_root/ | `-- features |-- awesomeness.feature |-- greatest_ever.feature
  • 40. project_root/ | `-- features |-- awesomeness.feature |-- greatest_ever.feature `-- support |-- env.rb `-- other_helpers.rb
  • 41. project_root/ | `-- features |-- awesomeness.feature |-- greatest_ever.feature `-- support |-- env.rb `-- other_helpers.rb |-- step_definitions | |-- domain_concept_A.rb | `-- domain_concept_B.rb
  • 43. Step Deļ¬nition Given /^a widget$/ do Given a widget #codes go here end
  • 44. When /^I search by director for "([^"]*)"$/ do |director| end
  • 45. Regexp Capture -> Yielded Variable When /^I search by director for "([^"]*)"$/ do |director| end
  • 46. When /^I search by director for "([^"]*)"$/ do |director| Ā Ā visit advanced_search_path Ā Ā fill_in "By Director", :with => director Ā Ā click_button "Search" end Webrat, Webdriver, Watir, etc..
  • 47. Not Just for Ruby
  • 48. When /^I search by director for "([^"]*)"$/ do |director| end [Given(@"^I search by director for "([^"]*)"$")] public void searchDirector(String director) { } http://wiki.github.com/richardlawrence/Cuke4Nuke/
  • 50. Gherkin Ragel
  • 51. Gherkin Ragel C, C++, Ruby, Java, .net, etc,
  • 52. Gherkin Ragel C, C++, Ruby, Java, .net, etc, http://specļ¬‚ow.org/
  • 54. When /^I search by director for "([^"]*)"$/ do |director| end @When("^I search by director for "([^"]*)"$") public void searchDirector(String director) { } When("^I search by director for "([^"]*)"$"{ String d -> } (When #"^I search by director for "([^"]*)"$" Ā Ā (fn [director] )) When("^I search by director for "([^"]*)"$"{ d: String => }
  • 55. Uhh... this just seems like more work for me.
  • 56. Scenario Outline: search by director Given the following movies are in stock: | Title | Director | Year | | Jaws | Steven Spielberg | 1975 | | Star Wars | George Lucas | 1975 | | Dawn of the Dead | George Romero | 1978 | | E.T. | Steven Spielberg | 1982 | When I search for "<Director Query>" under "Director" Then I the search results should be "<Search Results>" Examples: | Director Query | Search Results | | Steve | E.T., Jaws | | George | Dawn of the Dead, Star Wars | | Zombie guy | Dawn of the Dead | | Lucas | Star Wars | Scenario: search by director on a full moon Given that it is a full moon ...
  • 57. Scenario Outline: search by director Given the following movies are in stock: | Title | Director | Year | | Jaws | Steven Spielberg | 1975 | | Star Wars | George Lucas | 1975 | | Dawn of the Dead | George Romero | 1978 | | E.T. | Steven Spielberg | 1982 | When I search for "<Director Query>" under "Director" Then I the search results should be "<Search Results>" Examples: | Director Query | Search Results | | Steve | E.T., Jaws | | George | Dawn of the Dead, Star Wars | | Zombie guy | Dawn of the Dead | | Lucas | Star Wars | Scenario: search by director on a full moon Given that it is a full moon ...
  • 58. You know where to begin and end. Yo
  • 59. You know when you broke something.
  • 60.
  • 61.
  • 63. Model
  • 68.
  • 69.
  • 73. Go Down A Gear
  • 80. REFACTOR and REPEAT
  • 81. Next set of slides stolen from Aslak HellesĆøy, creator of http://www.slideshare.net/aslak.hellesoy/cuke4duke-javazone-2009
  • 82. Feature: code-breaker submits guess In order to make time pass when I'm alone As a player I want to play the against a machine Scenario: all correct Given the secret code is "r g y c" When I guess "r g y c" Then the mark should be "bbbb"
  • 83.
  • 84. $ gem install cucumber $ cucumber features
  • 85. <repositories> <repository> <id>cukes</id> <url>http://cukes.info/maven</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>cukes</id> <url>http://cukes.info/maven</url> </pluginRepository> </pluginRepositories>
  • 86. <dependencies> <dependency> <groupId>cuke4duke</groupId> <artifactId>cuke4duke</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.picocontainer</groupId> <artifactId>picocontainer</artifactId> <version>2.8.3</version> </dependency> </dependencies>
  • 87. <plugin> <groupId>cuke4duke</groupId> <artifactId>cuke4duke-maven-plugin</artifactId> <configuration> <jvmArgs> <jvmArg> -Dcuke4duke.objectFactory= cuke4duke.internal.java.PicoFactory </jvmArg> </jvmArgs> <cucumberArgs> <cucumberArg>${basedir}/src/test/java</cucumberArg> </cucumberArgs> <gems> <gem>install cuke4duke --version x.y.x</gem> </gems> </configuration> </plugin>
  • 88. $ mvn integration-test -Dcucumber.installGems=true
  • 89. Feature: code-breaker submits guess In order to make time pass when I'm alone As a player I want to play the against a machine Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # features/c..s.feature:7 When I guess "r g y c" # features/c..s.feature:8 Then the mark should be "bbbb" # features/c..s.feature:9 1 scenario (1 undefined) 3 steps (3 undefined) 0m0.076s
  • 90. You can implement step definitions for undefined steps with these snippets: @Given("^the secret code is "([^"]*)"$") @Pending public void theSecretCodeIsRGYC_(String arg1) { } @When("^I guess "([^"]*)"$") @Pending public void iGuessRGYC_(String arg1) { } @Then("^the mark should be "([^"]*)"$") @Pending public void theMarkShouldBeBbbb_(String arg1) { }
  • 91. package codebreaker; import cuke4duke.*; public class CodeBreakerSteps { @Given("^the secret code is "([^"]*)"$") @Pending public void theSecretCodeIs(String code) { } @When("^I guess "([^"]*)"$") @Pending public void iGuess(String guess) { } @Then("^the mark should be "([^"]*)"$") @Pending public void theMarkShouldBe(String mark) { } }
  • 92. $ mvn integration-test Feature: code-breaker submits guess In order to make time pass when I'm alone As a player I want to play the against a machine Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # public void theS..(..) TODO (Cucumber::Pending) f../c..s.feature:7:in `Given the secret code is "r g y c"' When I guess "r g y c" # public void iGue..(..) Then the mark should be "bbbb" # public void theM..(..) 1 scenario (1 pending) 3 steps (2 skipped, 1 pending) 0m0.079s
  • 93. Given the secret code is "r g y c" # public void codebreaker.GameSteps .theSecretCodeIs(java.lang.String)
  • 94. Given the secret code is "r g y c"
  • 95. Given the secret code is "r g y c" @Given("^the secret code is "([^"]*)"$") public void theSecretCodeIs(String code) { }
  • 96. public class GameSteps { private Game game; @Given("^the secret code is "([^"]*)"$") public void theSecretCodeIs(String code) { game = new Game(code); } }
  • 97. Compilation failure src/test/java/codebreaker/ CodeBreakerSteps.java:[6,12] cannot find symbol symbol : class Game location: class codebreaker.CodeBreakerSteps
  • 98.
  • 99. package codebreaker; public class Game { public Game(String code) { } }
  • 100. $ mvn integration-test Feature: code-breaker submits guess In order to make time pass when I'm alone As a player I want to play the against a machine Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # public void theS..(..) When I guess "r g y c" # public void iGue..(..) TODO (Cucumber::Pending) f../c..s.feature:8:in `When I guess "r g y c"' Then the mark should be "bbbb" # public void theM..(..) 1 scenario (1 pending) 3 steps (1 skipped, 1 pending, 1 passed) 0m0.112s
  • 101.
  • 102. $ mvn integration-test Feature: code-breaker submits guess In order to make time pass when I'm alone As a player I want to play the against a machine Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # public void theS..(..) When I guess "r g y c" # public void iGue..(..) Then the mark should be "bbbb" # public void theM..(..) 1 scenario (1 passed) 3 steps (3 passed) 0m0.121s
  • 103. Scenario: all correct Given the secret code is "r g y c" When I guess "r g y c" Then the mark should be "bbbb" Scenario: 2 wrong pos, 2 correct Given the secret code is "r g y c" When I guess "r g c y" Then the mark should be "bbww"
  • 104. Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # public void theS..(..) When I guess "r g y c" # public void iGue..(..) Then the mark should be "bbbb" # public void theM..(..) Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # public void theS..(..) When I guess "r g y c" # public void iGue..(..) Then the mark should be "bbbb" # public void theM..(..) org.junit.ComparisonFailure: expected:<bb[bb]> but was:<bb[ww]> (NativeException) codebreaker/CodeBreakerSteps.java:20:in `theMarkShouldBe' features/codebreaker_submits_guess.feature:14:in `Then the mark should be "bbww"' 1 scenario (1 failed, 1 passed) 3 steps (1 failed, 3 passed) 0m0.121s
  • 105.
  • 106. Scenario: all correct Given the secret code is "r g y c" When I guess "r g y c" Then the mark should be "bbbb" Scenario: 2 wrong pos, 2 correct Given the secret code is "r g y c" When I guess "r g c y" Then the mark should be "bbww"
  • 107. Scenario Outline: submit guess Given the secret code is "<code>" When I guess "<guess>" Then the mark should be "<mark>" Examples: | code | guess | mark | | r g y c | r g y c | bbbb | | r g y c | r g c y | bbww | | r g y c | y r g c | bwww | | r g y c | c r g y | wwww |
  • 109. Tags
  • 110. @store @lucene Feature: Advanced Search ... @wip Scenario: search by director ... @proposed @pending_ui Scenario: items not carried ... @nightly Scenario: long running ... @third_party Scenario: search Amazon ...
  • 111. @store @lucene Feature: Advanced Search ... @wip Scenario: search by director ... @proposed @pending_ui Scenario: items not carried ... @nightly Scenario: long running ... @third_party Scenario: search Amazon ...
  • 112. @store @lucene Feature: Advanced Search ... @wip Tag Exclusion Scenario: search by director ... @proposed @pending_ui cucumber --tags ~@proposed Scenario: items not carried ... @nightly Scenario: long running ... @third_party Scenario: search Amazon ...
  • 113. @store @lucene Feature: Advanced Search ... @wip Scenario: search by director ... @proposed @pending_ui Scenario: items not carried ... @nightly Scenario: long running ... @third_party Scenario: search Amazon ...
  • 114. @store @lucene Feature: Advanced Search ... @wip Scenario: search by director ... @proposed @pending_ui Scenario: items --tags @wip:2 cucumber not carried --wip ... @nightly Scenario: long running ... @third_party Scenario: search Amazon ...
  • 115. @store @lucene Feature: Advanced Search ... @wip Limit scenarios in ļ¬‚ow Scenario: search by director ... @proposed @pending_ui Scenario: items --tags @wip:2 cucumber not carried --wip ... @nightly Scenario: long running ... @third_party Scenario: search Amazon ...
  • 116. @store @lucene Feature: Advanced Search ... @wip Limit scenarios in ļ¬‚ow Scenario: search by director ... @proposed @pending_ui Scenario: items --tags @wip:2 cucumber not carried --wip ... @nightly Expect failure - Success == Failure Scenario: long running ... @third_party Scenario: search Amazon ...
  • 117. Hooks Before do end After do |scenario| end World do end World(MyModule) World(HerModule)
  • 118. Tagged Hooks Before('@im_special', '@me_too') do @icecream = true end @me_too Feature: Sit Feature: Lorem @im_special Scenario: Ipsum Scenario: Amet Scenario: Dolor Scenario: Consec
  • 119. Acceptance Tests == End-to-End?
  • 120.
  • 122. Slow Integrated Fast Isolated
  • 123. Slow Integrated Fast Isolated
  • 124. Slow Integrated HtmlUnit V8 Fast Isolated
  • 125. Slow Integrated HtmlUnit V8 Fast Isolated
  • 127. patient b uyer As an im ine my search Given... I want to ref find wha t When... So that I Iw can ant quic kly Then...
  • 128. patient b uyer As an im ine my search Given... I want to ref find wha t When... So that I Iw can ant quic kly Then...
  • 129. patient b uyer As an im ine my search Given... I want to ref find wha t When... So that I Iw can ant quic kly Then...
  • 130. patient b uyer As an im ine my search Given... I want to ref find wha t When... So that I Iw can ant quic kly Then...
  • 131. patient b uyer As an im ine my search Given... I want to ref find wha t When... So that I Iw can ant quic kly Then...
  • 132. Dead er t ient buy As an impa m y search I want to refine t find wha So that I can y I wan t quickl D PR
  • 133. Dead Living Feature: Advanced Search As an impatient buyer I want to refine my search So that I can find what I want quickly Scenario Outline: search by director er Given the following movies are in stock: t ient buy an impa | Title | Director | Year | As m y search | Jaws | Steven Spielberg | 1975 | I want to refine t | Star Wars | George Lucas | 1975 | find wha | Dawn of the Dead | George Romero | 1978 | that I can | E.T. | Steven Spielberg | 1982 | So y When I search for "<Director Query>" under "Director" I wan t quickl Then I the search results should be "<Search Results>" Examples: | Director Query | Search Results | | Steve | E.T., Jaws | | George | Dawn of the Dead, Star Wars | D | Lucas | Star Wars | PR
  • 135. Feature: Advanced Search As an impatient buyer I want to refine my search So that I can find what I want quickly
  • 136. Feature: Advanced Search As an impatient buyer I want to refine my search So that I can find what I want quickly Scenario: search by director Given movies directed by "Steven Spielberg" are in stock When I search by director for "Spielberg" Then I should see all of the movies directed by "Steven Spielberg"
  • 137. Feature: Advanced Search As an impatient buyer I want to refine my search So that I can find what I want quickly Declarative Scenario: search by director Given movies directed by "Steven Spielberg" are in stock When I search by director for "Spielberg" Then I should see all of the movies directed by "Steven Spielberg"
  • 138. Feature: Advanced Search As an impatient buyer I want to refine my search So that I can find what I want quickly Imperative Scenario: search by director Given movies directed by "Steven Spielberg" are in stock And I am on the "Advanced Search" page When I fill in "Spielberg" for "Director" And press "Submit" Then I should see all of the movies directed by "Steven Spielberg"
  • 139. Feature: Advanced Search As an impatient buyer I want to refine my search So that I can find what I want quickly Imperative Scenario: search by director Given movies directed by "Steven Spielberg" are in stock And I am on the "Advanced Search" page When I fill in "Spielberg" for "Director" And press "Submit" Then I should see all of the movies directed by "Steven Spielberg" I like it! I actually know how a user can use it!
  • 141. Scenario: successful login Given I'm on the login page When I fill in "jimmy" for "Login" And fill in "password" for "Password" And click "Login" Then I should see "Welcome back jimmy!"
  • 143. Scenario: change password success Given I'm on the login page When I fill in "jimmy" for "Login" And fill in "password" for "Password" And click "Login" Then I should see "Welcome back jimmy!"
  • 144. Scenario: change password success Given I'm on the login page When I fill in "jimmy" for "Login" And fill in "password" for "Password" And click "Login" Then I should see "Welcome back jimmy!" When I click "Change Password" And fill in the following | Old Password | password | | New Password | brand-new | | Confirmation | brand-new | And click "Change Password" Then I should see "Your password has been changed."
  • 145. Scenario: change password success Given I'm on the login page When I fill in "jimmy" for "Login" And fill in "password" for "Password" And click "Login" Then I should see "Welcome back jimmy!" When I click "Change Password" Incidental Details And fill in the following | Old Password | password | | New Password | brand-new | | Confirmation | brand-new | And click "Change Password" Then I should see "Your password has been changed."
  • 146. Scenario: change password success Given I'm logged in When I click "Change Password" Hide the noise! And fill in the following | Old Password | password | | New Password | brand-new | | Confirmation | brand-new | And click "Change Password" Then I should see "Your password has been changed."
  • 147. Resources http://cukes.info http://wiki.github.com/aslakhellesoy/cuke4duke/ http://blog.dannorth.net/whats-in-a-story/ http://blog.josephwilk.net/ruby/rocket-fuelled-cucumbers.html http://benmabey.com/2008/05/19/imperative-vs- declarative-scenarios-in-user-stories.html