狠狠撸

狠狠撸Share a Scribd company logo
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"
Cucumber: Automating the Requirements Language You Already Speak
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       |
Cucumber: Automating the Requirements Language You Already Speak
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.
Cucumber: Automating the Requirements Language You Already Speak
Cucumber: Automating the Requirements Language You Already Speak
Outside-In
Model
Controller
  Model
View
Controller
  Model
UI/UX
  View
Controller
  Model
UI/UX
  View
Controller
  Model
Cucumber: Automating the Requirements Language You Already Speak
Cucumber: Automating the Requirements Language You Already Speak
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"
Cucumber: Automating the Requirements Language You Already Speak
$ 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
Cucumber: Automating the Requirements Language You Already Speak
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
Cucumber: Automating the Requirements Language You Already Speak
$ 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
Cucumber: Automating the Requirements Language You Already Speak
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?
Cucumber: Automating the Requirements Language You Already Speak
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 (6)

Github flow
Github flowGithub flow
Github flow
Ben Mabey
?
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with Cucumber
Ben Mabey
?
Outside-In Development With Cucumber
Outside-In Development With CucumberOutside-In Development With Cucumber
Outside-In Development With Cucumber
Ben Mabey
?
Disconnecting the Database with ActiveRecord
Disconnecting the Database with ActiveRecordDisconnecting the Database with ActiveRecord
Disconnecting the Database with ActiveRecord
Ben Mabey
?
SVD and the Netflix Dataset
SVD and the Netflix DatasetSVD and the Netflix Dataset
SVD and the Netflix Dataset
Ben 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 RSpec
Ben Mabey
?
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with Cucumber
Ben Mabey
?
Outside-In Development With Cucumber
Outside-In Development With CucumberOutside-In Development With Cucumber
Outside-In Development With Cucumber
Ben Mabey
?
Disconnecting the Database with ActiveRecord
Disconnecting the Database with ActiveRecordDisconnecting the Database with ActiveRecord
Disconnecting the Database with ActiveRecord
Ben Mabey
?
SVD and the Netflix Dataset
SVD and the Netflix DatasetSVD and the Netflix Dataset
SVD and the Netflix Dataset
Ben 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 RSpec
Ben Mabey
?

Recently uploaded (20)

Get Your World777 ID and Explore Unlimited Possibilities!
Get Your World777 ID and Explore Unlimited Possibilities!Get Your World777 ID and Explore Unlimited Possibilities!
Get Your World777 ID and Explore Unlimited Possibilities!
world7co
?
Business, Art, Fashion, Technology and Alcohol Quiz for Odyssey '25 at IIIT D...
Business, Art, Fashion, Technology and Alcohol Quiz for Odyssey '25 at IIIT D...Business, Art, Fashion, Technology and Alcohol Quiz for Odyssey '25 at IIIT D...
Business, Art, Fashion, Technology and Alcohol Quiz for Odyssey '25 at IIIT D...
Ramish Abdali
?
Best IPTV Services for 2025:Top (10) Ranks in the USA
Best IPTV Services for 2025:Top (10) Ranks in the USABest IPTV Services for 2025:Top (10) Ranks in the USA
Best IPTV Services for 2025:Top (10) Ranks in the USA
dorothymcalister2
?
Billie Eilish Biography The Celeb Post.pdf
Billie Eilish Biography The Celeb Post.pdfBillie Eilish Biography The Celeb Post.pdf
Billie Eilish Biography The Celeb Post.pdf
Lionapk
?
Anime Where Kids Get Eaten – Dark Themes
Anime Where Kids Get Eaten – Dark ThemesAnime Where Kids Get Eaten – Dark Themes
Anime Where Kids Get Eaten – Dark Themes
Rohit Sharma
?
Naya Sachiv Linkedin Posts for Panchayat
Naya Sachiv Linkedin Posts for PanchayatNaya Sachiv Linkedin Posts for Panchayat
Naya Sachiv Linkedin Posts for Panchayat
Uddhav Parab
?
原版复刻加拿大道格拉斯学院成绩单(Douglas毕业证书) 文凭
原版复刻加拿大道格拉斯学院成绩单(Douglas毕业证书) 文凭原版复刻加拿大道格拉斯学院成绩单(Douglas毕业证书) 文凭
原版复刻加拿大道格拉斯学院成绩单(Douglas毕业证书) 文凭
taqyed
?
Britney Spears Biography The Celeb Post.pdf
Britney Spears Biography The Celeb Post.pdfBritney Spears Biography The Celeb Post.pdf
Britney Spears Biography The Celeb Post.pdf
Lionapk
?
Top Producer Elston Richardson’s Musical Mastery.pdf
Top Producer Elston Richardson’s Musical Mastery.pdfTop Producer Elston Richardson’s Musical Mastery.pdf
Top Producer Elston Richardson’s Musical Mastery.pdf
Elston Lindsay Richardson
?
NEW-MiniTool Partition Wizard Crack Latest Version?
NEW-MiniTool Partition Wizard Crack Latest Version?NEW-MiniTool Partition Wizard Crack Latest Version?
NEW-MiniTool Partition Wizard Crack Latest Version?
crackstore786
?
IPTV Service vs. Cable TV_ Which is Better for You.pdf
IPTV Service vs. Cable TV_ Which is Better for You.pdfIPTV Service vs. Cable TV_ Which is Better for You.pdf
IPTV Service vs. Cable TV_ Which is Better for You.pdf
Charles N. Eldridge
?
VR_AR_Video_Production_Vastvik_Films.pptx
VR_AR_Video_Production_Vastvik_Films.pptxVR_AR_Video_Production_Vastvik_Films.pptx
VR_AR_Video_Production_Vastvik_Films.pptx
Vastvik Films
?
With the Best IPTV Service Enjoy Live TV, Sports & Movies!
With the Best IPTV Service Enjoy Live TV, Sports & Movies!With the Best IPTV Service Enjoy Live TV, Sports & Movies!
With the Best IPTV Service Enjoy Live TV, Sports & Movies!
dorothymcalister2
?
Kim Kardashian Biography The Celeb Post.pdf
Kim Kardashian Biography The Celeb Post.pdfKim Kardashian Biography The Celeb Post.pdf
Kim Kardashian Biography The Celeb Post.pdf
Lionapk
?
Monique Alexander_ A Journey Through the Adult Entertainment Industry.docx
Monique Alexander_ A Journey Through the Adult Entertainment Industry.docxMonique Alexander_ A Journey Through the Adult Entertainment Industry.docx
Monique Alexander_ A Journey Through the Adult Entertainment Industry.docx
voice ofarticle
?
>parallel desktop Crack Latest Free 2025
>parallel desktop Crack Latest Free 2025>parallel desktop Crack Latest Free 2025
>parallel desktop Crack Latest Free 2025
crackstore786
?
Latest-Minitab Crack Free Download 2025?
Latest-Minitab Crack Free Download 2025?Latest-Minitab Crack Free Download 2025?
Latest-Minitab Crack Free Download 2025?
pepjin1
?
A Brief Introduction About David Crowder
A Brief Introduction About David CrowderA Brief Introduction About David Crowder
A Brief Introduction About David Crowder
David Crowder
?
A Brief Introduction About David Crowder
A Brief Introduction About David CrowderA Brief Introduction About David Crowder
A Brief Introduction About David Crowder
David Crowder
?
SUBWAY-SURF Game-Powerpoint-Template.pptx
SUBWAY-SURF Game-Powerpoint-Template.pptxSUBWAY-SURF Game-Powerpoint-Template.pptx
SUBWAY-SURF Game-Powerpoint-Template.pptx
RicaNiaLetran
?
Get Your World777 ID and Explore Unlimited Possibilities!
Get Your World777 ID and Explore Unlimited Possibilities!Get Your World777 ID and Explore Unlimited Possibilities!
Get Your World777 ID and Explore Unlimited Possibilities!
world7co
?
Business, Art, Fashion, Technology and Alcohol Quiz for Odyssey '25 at IIIT D...
Business, Art, Fashion, Technology and Alcohol Quiz for Odyssey '25 at IIIT D...Business, Art, Fashion, Technology and Alcohol Quiz for Odyssey '25 at IIIT D...
Business, Art, Fashion, Technology and Alcohol Quiz for Odyssey '25 at IIIT D...
Ramish Abdali
?
Best IPTV Services for 2025:Top (10) Ranks in the USA
Best IPTV Services for 2025:Top (10) Ranks in the USABest IPTV Services for 2025:Top (10) Ranks in the USA
Best IPTV Services for 2025:Top (10) Ranks in the USA
dorothymcalister2
?
Billie Eilish Biography The Celeb Post.pdf
Billie Eilish Biography The Celeb Post.pdfBillie Eilish Biography The Celeb Post.pdf
Billie Eilish Biography The Celeb Post.pdf
Lionapk
?
Anime Where Kids Get Eaten – Dark Themes
Anime Where Kids Get Eaten – Dark ThemesAnime Where Kids Get Eaten – Dark Themes
Anime Where Kids Get Eaten – Dark Themes
Rohit Sharma
?
Naya Sachiv Linkedin Posts for Panchayat
Naya Sachiv Linkedin Posts for PanchayatNaya Sachiv Linkedin Posts for Panchayat
Naya Sachiv Linkedin Posts for Panchayat
Uddhav Parab
?
原版复刻加拿大道格拉斯学院成绩单(Douglas毕业证书) 文凭
原版复刻加拿大道格拉斯学院成绩单(Douglas毕业证书) 文凭原版复刻加拿大道格拉斯学院成绩单(Douglas毕业证书) 文凭
原版复刻加拿大道格拉斯学院成绩单(Douglas毕业证书) 文凭
taqyed
?
Britney Spears Biography The Celeb Post.pdf
Britney Spears Biography The Celeb Post.pdfBritney Spears Biography The Celeb Post.pdf
Britney Spears Biography The Celeb Post.pdf
Lionapk
?
Top Producer Elston Richardson’s Musical Mastery.pdf
Top Producer Elston Richardson’s Musical Mastery.pdfTop Producer Elston Richardson’s Musical Mastery.pdf
Top Producer Elston Richardson’s Musical Mastery.pdf
Elston Lindsay Richardson
?
NEW-MiniTool Partition Wizard Crack Latest Version?
NEW-MiniTool Partition Wizard Crack Latest Version?NEW-MiniTool Partition Wizard Crack Latest Version?
NEW-MiniTool Partition Wizard Crack Latest Version?
crackstore786
?
IPTV Service vs. Cable TV_ Which is Better for You.pdf
IPTV Service vs. Cable TV_ Which is Better for You.pdfIPTV Service vs. Cable TV_ Which is Better for You.pdf
IPTV Service vs. Cable TV_ Which is Better for You.pdf
Charles N. Eldridge
?
VR_AR_Video_Production_Vastvik_Films.pptx
VR_AR_Video_Production_Vastvik_Films.pptxVR_AR_Video_Production_Vastvik_Films.pptx
VR_AR_Video_Production_Vastvik_Films.pptx
Vastvik Films
?
With the Best IPTV Service Enjoy Live TV, Sports & Movies!
With the Best IPTV Service Enjoy Live TV, Sports & Movies!With the Best IPTV Service Enjoy Live TV, Sports & Movies!
With the Best IPTV Service Enjoy Live TV, Sports & Movies!
dorothymcalister2
?
Kim Kardashian Biography The Celeb Post.pdf
Kim Kardashian Biography The Celeb Post.pdfKim Kardashian Biography The Celeb Post.pdf
Kim Kardashian Biography The Celeb Post.pdf
Lionapk
?
Monique Alexander_ A Journey Through the Adult Entertainment Industry.docx
Monique Alexander_ A Journey Through the Adult Entertainment Industry.docxMonique Alexander_ A Journey Through the Adult Entertainment Industry.docx
Monique Alexander_ A Journey Through the Adult Entertainment Industry.docx
voice ofarticle
?
>parallel desktop Crack Latest Free 2025
>parallel desktop Crack Latest Free 2025>parallel desktop Crack Latest Free 2025
>parallel desktop Crack Latest Free 2025
crackstore786
?
Latest-Minitab Crack Free Download 2025?
Latest-Minitab Crack Free Download 2025?Latest-Minitab Crack Free Download 2025?
Latest-Minitab Crack Free Download 2025?
pepjin1
?
A Brief Introduction About David Crowder
A Brief Introduction About David CrowderA Brief Introduction About David Crowder
A Brief Introduction About David Crowder
David Crowder
?
A Brief Introduction About David Crowder
A Brief Introduction About David CrowderA Brief Introduction About David Crowder
A Brief Introduction About David Crowder
David Crowder
?
SUBWAY-SURF Game-Powerpoint-Template.pptx
SUBWAY-SURF Game-Powerpoint-Template.pptxSUBWAY-SURF Game-Powerpoint-Template.pptx
SUBWAY-SURF Game-Powerpoint-Template.pptx
RicaNiaLetran
?

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"
  • 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 |
  • 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.
  • 63. Model
  • 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"
  • 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
  • 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
  • 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
  • 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?
  • 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