Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Outside in development with Cucumber and Rspec

Joseph Wilk
September 22, 2011

Outside in development with Cucumber and Rspec

Talk given by Joseph Wilk at Scotland on Rails 2009. Examines how Cucumber and Rspec fit together in the testing workflow, how and why Cucumber is useful and how it works. Walks through a simple example based on renting DVDs showing how to use Cucumber and some of the best practices. Looks at how Webrat can drive Selenium to in-turn drive Cucumber features through the browser.

Joseph Wilk

September 22, 2011
Tweet

More Decks by Joseph Wilk

Other Decks in Programming

Transcript

  1. utside
    in
    Development
    Cucumber Rspec
    Joseph Wilk / http://blog.josephwilk.net

    View full-size slide

  2. Why are you here?

    View full-size slide

  3. Why are you here?
    In order to ...

    View full-size slide

  4. Why are you here?
    In order to ...
    As a Scotland on Rails attendee

    View full-size slide

  5. Why are you here?
    In order to ...
    As a Scotland on Rails attendee
    I want ...

    View full-size slide

  6. What is your
    Acceptance Criteria?

    View full-size slide

  7. Scenario: Happy SoR attendees
    Given people turned up
    When Joseph talks
    Then everyone should acquire some new knowledge
    And no-one should fall asleep
    And no rotten food should be thrown

    View full-size slide

  8. Outside-in
    Models
    Views
    Controllers
    User
    Browser

    View full-size slide

  9. Cucumber
    Rspec
    “The feature
    you wished you
    had”
    “The
    components
    and the
    interactions
    you wish you
    had”
    Models
    Views
    Controllers

    View full-size slide

  10. Cucumber
    Rspec
    “The feature
    you wished you
    had”
    “The
    components
    and the
    interactions
    you wish you
    had”
    Models
    Views
    Controllers

    View full-size slide

  11. Cucumber
    Rspec
    “The feature
    you wished you
    had”
    “The
    components
    and the
    interactions
    you wish you
    had”
    Models
    Views
    Controllers

    View full-size slide

  12. Cucumber / Scenario

    View full-size slide

  13. Cucumber / Scenario

    View full-size slide

  14. Cucumber / Scenario
    Rspec / code
    examples

    View full-size slide

  15. Cucumber / Scenario
    Rspec / code
    examples

    View full-size slide

  16. Cucumber / Scenario
    Rspec / code
    examples

    View full-size slide

  17. Cucumber / Scenario
    Rspec / code
    examples

    View full-size slide

  18. Cucumber / Scenario
    Rspec / code
    examples

    View full-size slide

  19. :rspec => route finder
    :cucumber => destination
    London Edinburgh

    View full-size slide

  20. Behaviour Driven Development
    with elegance and joy

    View full-size slide

  21. Behaviour Driven Development
    with elegance and joy
    Just Cuke it!

    View full-size slide

  22. Plaintext
    Features
    Ruby
    step definitions

    View full-size slide

  23. Cucumber Feature
    Feature: Be awesome
    Narrative
    Scenario: title
    Given
    And
    When
    And
    Then
    And
    Not
    executed
    Example of
    behaviour

    View full-size slide

  24. Plaintext
    Ruby tests
    Cucumber
    Given /^we like (.*)$/i do |fruit|
    fruit.should == 'cukes'
    #assert_equal(fruit, 'cukes')
    end
    Given we like cukes
    Feature
    Step
    definition
    regexp match

    View full-size slide

  25. Plug and Pray
    Rails
    Plaintext Ruby tests
    Merb Sinatra
    Rspec
    TestUnit
    iPhone
    Cucumber
    Ruby-Gnome2 Cucumber

    View full-size slide

  26. Cucumber English

    View full-size slide

  27. concombre
    Ωϡ΢Ϧ
    Gurke
    Cucumber
    pepino
    cetriolo
    agurk
    ﺭﺎﻴﳋﺍ
    ketimun
    Japanese
    German
    English
    Arabic
    Indonisean
    Italian
    Spanish
    Danish
    French
    огурец Russian Chinese
    ԫӝ
    য়੉ Korean
    gurka Swedish
    Romanian
    castravete
    ogórek Polish

    View full-size slide

  28. concombre
    Ωϡ΢Ϧ
    Gurke
    Cucumber
    pepino
    cetriolo
    agurk
    ﺭﺎﻴﳋﺍ
    ketimun
    Japanese
    German
    English
    Arabic
    Indonisean
    Italian
    Spanish
    Danish
    French
    огурец Russian Chinese
    ԫӝ
    য়੉ Korean
    gurka Swedish
    Romanian
    castravete
    ogórek Polish
    Treetop Rocks
    ANTLR
    could rock
    harder

    View full-size slide

  29. Webrat
    Love
    visit home_path
    click_link "Web"
    fill_in "Email", :with => "Rat”
    click_button "Love"
    Bansky

    View full-size slide

  30. Return On Investment
    Cucumber Feature

    View full-size slide

  31. Return On Investment
    Cucumber Feature
    • Token Conversation

    View full-size slide

  32. Return On Investment
    Cucumber Feature
    • Token Conversation
    • Acceptance Criteria

    View full-size slide

  33. Return On Investment
    Cucumber Feature
    • Token Conversation
    • Acceptance Criteria
    • Design

    View full-size slide

  34. Return On Investment
    Cucumber Feature
    • Token Conversation
    • Acceptance Criteria
    • Design
    • Documentation

    View full-size slide

  35. Return On Investment
    Cucumber Feature
    • Token Conversation
    • Acceptance Criteria
    • Design
    • Documentation
    • Functional test

    View full-size slide

  36. Return On Investment
    Cucumber Feature
    • Token Conversation
    • Acceptance Criteria
    • Design
    • Documentation
    • Functional test
    • Integration test

    View full-size slide

  37. Token for Conversation

    View full-size slide

  38. Feature Request
    I want members to be able to
    rent a movie with a priority
    indicating how much they
    want to see the film

    View full-size slide

  39. Show me the _ _ _ _ _

    View full-size slide

  40. Show me the _ _ _ _ _
    VA LU E

    View full-size slide

  41. Root Cause Analysis

    View full-size slide

  42. So we can maximise allocation of
    films
    Why?
    Root Cause Analysis

    View full-size slide

  43. Why?
    So we can maximise allocation of
    films
    Why?
    Keep customers happy
    Root Cause Analysis

    View full-size slide

  44. Why?
    Why?
    So we can maximise allocation of
    films
    Why?
    Keep customers happy
    So they continue with their
    subscriptions
    Root Cause Analysis

    View full-size slide

  45. Why?
    Why?
    So we can maximise allocation of
    films
    Why?
    Keep customers happy
    So they continue with their
    subscriptions
    Root Cause Analysis

    View full-size slide

  46. Lets write our
    Cucumber feature

    View full-size slide

  47. Feature: select a movie to rent with priority
    In order to maximise allocation of films
    The website user
    Needs to be able to add movies to their rental list with a priority
    Feature (terrible)
    Role
    Value
    Feature

    View full-size slide

  48. Feature: select a movie to rent with priority
    In order to maximise allocation of films
    The website user
    Needs to be able to add movies to their rental list with a priority
    Feature (terrible)
    Narrative
    Role
    Value
    Feature

    View full-size slide

  49. Feature: select a movie to rent with priority
    In order to maximise allocation of films
    The website user
    Needs to be able to add movies to their rental list with a priority
    Feature (terrible)
    Role
    Value
    Feature

    View full-size slide

  50. Feature (terrible)
    Feature: select a movie to rent with priority
    In order to maximise allocation of films
    The website user
    Needs to be able to add movies to their rental list with a priority

    View full-size slide

  51. Feature: select a movie to rent with priority
    In order to maximise allocation of films
    The website user
    Needs to be able to add movies to their rental list with a priority
    Feature (terrible)
    Noise

    View full-size slide

  52. Feature: select a movie to rent with priority
    In order to maximise allocation of films
    The website user
    Needs to be able to add movies to their rental list with a priority
    Feature (terrible)
    Too generic
    role

    View full-size slide

  53. Feature: select a movie to rent with priority
    In order to maximise allocation of films
    The website user
    Needs to be able to add movies to their rental list with a priority
    Feature (terrible)
    Too generic
    role
    Film member

    View full-size slide

  54. Feature: select a movie to rent with priority
    In order to maximise allocation of films
    The website user
    Needs to be able to add movies to their rental list with a priority
    Feature (terrible)
    Role can change
    feature
    Film member

    View full-size slide

  55. Feature: select a movie to rent with priority
    In order to maximise allocation of films
    The website user
    Needs to be able to add movies to their rental list with a priority
    Feature (terrible)
    Role can change
    feature
    Film Member selects a movie to rent with priority
    Film member

    View full-size slide

  56. Feature (terrible)
    Nice
    Feature: select a movie to rent with priority
    In order to maximise allocation of films
    The website user
    Needs to be able to add movies to their rental list with a priority
    Film Member selects a movie to rent with priority
    Film member

    View full-size slide

  57. Acceptance
    Definition of Done.

    View full-size slide

  58. Scenarios
    Feature: Film Member selects a movie to rent with priority
    In order to maximise allocation of films
    The Film member
    Needs to add movies to their rental list with a priority
    Scenario: High priority

    View full-size slide

  59. Scenarios
    Feature: Film Member selects a movie to rent with priority
    In order to maximise allocation of films
    The Film member
    Needs to add movies to their rental list with a priority
    Scenario: High priority
    Then I should see "My rental list"
    And I should see "Casshern" in my rental list
    And "Casshern" should be marked as "High priority"

    View full-size slide

  60. Scenarios
    Feature: Film Member selects a movie to rent with priority
    In order to maximise allocation of films
    The Film member
    Needs to add movies to their rental list with a priority
    Scenario: High priority
    Then I should see "My rental list"
    And I should see "Casshern" in my rental list
    And "Casshern" should be marked as "High priority"
    When I choose "High priority"
    And I press "Rent"

    View full-size slide

  61. Scenarios
    Feature: Film Member selects a movie to rent with priority
    In order to maximise allocation of films
    The Film member
    Needs to add movies to their rental list with a priority
    Scenario: High priority
    Then I should see "My rental list"
    And I should see "Casshern" in my rental list
    And "Casshern" should be marked as "High priority"
    When I choose "High priority"
    And I press "Rent"
    Given I'm logged in
    And I am viewing the movie "Casshern"

    View full-size slide

  62. Let there be Cuking

    View full-size slide

  63. Demo
    High Resolution:
    http://www.screencast.com/t/aG1sE4N3Zq
    Low Resolution:
    http://www.vimeo.com/3910617

    View full-size slide

  64. Here’s one I
    Cuked earlier

    View full-size slide

  65. Demo
    High Resolution:
    http://www.screencast.com/t/tlBYxkKci
    Low Resolution
    http://www.vimeo.com/3911104

    View full-size slide

  66. Installing Cucumber
    $ sudo gem install cucumber
    $ script/plugin install git://github.com/aslakhellesoy/
    cucumber.git
    $ gem sources -a http://gems.github.com
    $ sudo gem install aslakhellesoy-cucumber

    View full-size slide

  67. Fixtures
    Scenario: search results found
    Given the Movies
    | title |
    | The colour white |
    | The colour red |
    | Casshern |
    When I search for "colour"
    Then I will see 2 results
    Scenario: search results found
    Given 2 films with "colour" in the title
    When I search for "colour"
    Then I will see 2 results
    Given /^the Movies$/i do |movie_hash|
    #{:title => "The colour white"},
    #{:title => "The colour red"},
    #{:title => "Casshern"}
    movies.hashes.each do |values|
    Movie.create!(values)
    end
    end

    View full-size slide

  68. Stick it to the World
    module NavigationHelpers
    def path_to(page_name)
    case page_name
    when /the homepage/
    root_path
    else
    raise "Can't find mapping from \"#{page_name}\" to a path."
    end
    end
    end
    World do |world|
    world.extend NavigationHelpers
    world
    end

    View full-size slide

  69. Hooks
    Hooks are GLOBAL!
    Before do
    # do something before each scenario.
    end
    After do
    #do something after each scenario
    end

    View full-size slide

  70. How many scenarios is
    enough?
    • Given/When/Then
    “Finite state machine” Uncle Bob
    • What’s the Return on Investment?

    View full-size slide

  71. Cowcumbers (Bad smells)
    “fit only for consumption by cows”

    View full-size slide

  72. Given /^dirty state$/ do
    @movie = Movie.create!
    end
    Given /^coupled by state$/ do
    @movie.title = "yucky"
    end
    Cowcumbers
    Tests without user value
    Relying on state (too much)
    Given /^does a user care$/ do
    response.current_url == ‘silly’
    end
    Given /^checking the db$/ do
    Movie.find(1).should_not == nil
    end

    View full-size slide

  73. Building your DSL

    View full-size slide

  74. Concrete vs Abstract
    Scenarios
    Concrete Abstract
    Domain understanding
    Given I go to the login page
    And I fill in "username" with "joseph"
    And I fill in "password" with "cuker"
    And I click "login"
    Given I'm logged in

    View full-size slide

  75. Calling steps from steps
    Given /I’m logged in/ do
    User.create!(:user => 'josephwilk', :password => "pass")
    Given 'I fill in "password" with "josephwilk"'
    Given 'I fill in "password" with "pass"'
    Given 'I click "login"'
    end

    View full-size slide

  76. Feature Request
    Can you add some of that
    funky AJAX stuff for the
    rent button

    View full-size slide

  77. JavaScript kills Webrat

    View full-size slide

  78. Watir, Selenium &
    Celerity
    Browser based
    • Watir
    • Selenium
    Headless Browser
    • Celerity
    • Culerity - http://
    github.com/langalex/
    culerity/tree/master

    View full-size slide

  79. Webrat / Selenium
    # Sets up the Rails environment for Cucumber
    ENV["RAILS_ENV"] ||= "selenium"
    require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
    require 'cucumber/rails/world'
    require 'cucumber/formatters/unicode'
    #Cucumber::Rails.use_transactional_fixtures
    require 'webrat'
    Webrat.configure do |config|
    config.mode = :selenium
    end
    require 'cucumber/rails/rspec'
    require 'webrat/core/matchers'
    Before do
    Movie.delete_all
    RentalRequest.delete_all
    end
    Turn off
    Switch to Selenium
    Manually cleanup

    View full-size slide

  80. Organising
    cucumber --profile rails --tags ~@js
    cucumber --profile browser --tags @js
    @in-progress
    Feature: Verify billing
    @js
    Scenario: Missing product description
    Scenario: Several products
    Tag

    View full-size slide

  81. Demo
    High Resolution:
    http://www.screencast.com/t/1jRSI6TvXWu
    Low Resolution:
    http://www.vimeo.com/3911241

    View full-size slide

  82. Further reading
    • http://cukes.info
    • http://wiki.github.com/
    aslakhellesoy/cucumber
    • http://rspec.info/
    • http://blog.josephwilk.net

    View full-size slide

  83. Thanks
    [email protected]
    http://github.com/josephwilk

    View full-size slide