Cucumber: How I Slice It
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Cucumber: How I Slice It

  • 6,578 views
Uploaded on

Cucumber is a tool for executable plain-text documentation. Skipping past "how to install..." etc, I jump right into how I'm actually using it in a large project.

Cucumber is a tool for executable plain-text documentation. Skipping past "how to install..." etc, I jump right into how I'm actually using it in a large project.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
6,578
On Slideshare
6,536
From Embeds
42
Number of Embeds
4

Actions

Shares
Downloads
99
Comments
0
Likes
6

Embeds 42

http://nhruby.org 18
http://www.slideshare.net 18
http://www.vaporbase.com 5
http://static.slideshare.net 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Cucumber: How I Slice It Jonathan Linowes Parkerhill Technology Group NH Ruby Group, January 15, 2009 Executable plain-text documentation
  • 2. Intro
    • See http://www.slideshare.net/bkeepers/behavior-driven-development-with-cucumber-presentation
    • Home http://wiki.github.com/aslakhellesoy/cucumber
  • 3. Uses
    • Collaboration, brainstorming with customer
    • Specification, refinement of requirements
    • Behavior driven development
    • View specs
    • Integration testing
    • Regression testing
  • 4. How I actually use it
    • Talking to myself (planning)
    • Keep track of what I'm working on (outlining)
    • Automate my manual testing (scripting)
    • Regression testing (confidence)
  • 5. When I use it
    • written first, in true BDD tao
    • written simultaneously with code and specs
    • written after the code is working
    • run as regression
    • run on deploy (cap deploy:features)
    • run with debugger
  • 6. Directories and files
    • Rails app root/
      • features/
        • [feature set]/
          • [feature].feature files
        • poetry_contest/
          • simple_clicking.feature
          • submitter_submits_new_submission.feature
        • step_definitions/
          • browser_steps.rb
          • account_steps.rb
          • project_steps.rb
          • poetry_contest_steps.rb
          • other [steps].rb files
        • support/
          • env.rb
  • 7. Demo – simple clicking
    • Feature: simple clicking
    • As someone interested in the Poetry Contest
    • I visit the project and view some pages
    • So I can learn more about the contest
    • Scenario: Anonymous user clicks submit
    • Given a Poetry Submissions setup
    • When I browse to the project "home" page
    • Then I should see a "Submit" link
    • And the page html should be valid
    • When I click the "Submit" link
    • Then I should see the "Poem Submission Form" page
    • And (show me)
  • 8. Given
    • Given /^a Poetry (.*) setup$/ do |setup|
    • @account ||= create_account( 'test' )
    • @project ||= create_project( 'poetry contest', @account )
    • case setup.downcase
    • when 'submissions':
    • poetry_submissions_setup
    • when 'submissions and reviews': poetry_submissions_and_reviews_setup
    • else puts "UNKNOWN POETRY SETUP"
    • end
    • end
    • Using instance variables for 'state'
    • My own 'factory' (create) methods
    • High level setup methods
  • 9. When
    • Using regexp conventions in matcher
    • Using quotes for named things
    • String#normalize: downcase, strip, _, etc
    • Assume current state (@project)
    • Webrat for requests
    • When /^I browse to the project "(.*)" page$/ do |page|
    • # browse refers to the url
    • page = '' if page == 'home'
    • visit "/#{@project.to_param}/#{page.normalize}"
    • end
    • When /^I click the "(.*)" link$/ do |link|
    • click_link link
    • end
  • 10. Then
    • Using webrat for asserts
    • Matches keywords like 'link$/' or 'page$/'
    • Natural language conveniences
        • Then I should see a “Foo” link
        • And a “Bar” link
    • App-specific conventions (h1 for page title)
    • Then /^(I should see a|a) "(.*)" link$/ do |see, link|
    • response.should have_tag("a", link)
    • end
    • Then /^(I should see the|the) "(.*)" page$/ do |see, h1_contents|
    • response.should have_tag("h1", h1_contents)
    • end
  • 11. Utilities
    • See http://www.vaporbase.com/postings/Show_me_the_response
    • Then /^the page html should be valid$/ do
    • # using ruby_tidy
    • assert_tidy
    • end
    • Then /^(show me)$/ do
    • show_me
    • #save_and_open_page
    • end
    • # support/env.rb
    • def show_me
    • name = response.request.request_uri.gsub(/[/#?]/,'-')
    • File.open(RAILS_ROOT + "/public/cucumber/#{name}.html", "w"){ |f| f.puts response.body }
    • system "open -a Firefox.app http://localhost:3000/cucumber/#{name}.html"
    • end
  • 12. Demo – scenario outline membership/invite_reviewer.feature:41 (29)
    • Runs once for each example
    • mail
    • Scenario Outline: invite existing users
    • Given I am logged in as a Manager member
    • And there is a <status> user with email &quot;invitee@example.com&quot;
    • When I invite the user to be a Reviewer
    • Then there should be a user with that email
    • And he should be Invited as a Reviewer member
    • And he should be sent a Invitation email
    • And I should see the &quot;Memberships&quot; resource table
    • And a Notice saying &quot;User successfully invited&quot;
    • Examples:
    • | status |
    • | Passive |
    • | Pending |
    • | Active |
  • 13. mailer_setup
    • # env.rb
    • def mailer_setup
    • ActionMailer::Base.delivery_method = :test
    • ActionMailer::Base.perform_deliveries = true
    • ActionMailer::Base.deliveries = []
    • end
    • def last_email_sent(index=-1)
    • ActionMailer::Base.deliveries[index]
    • end
    • # step
    • Then /^(.*) should be sent (a|an) (.*) email$/ do |who, a, dispatch|
    • (...)
    • case dispatch.downcase
    • when 'invitation'
    • last_email_sent.subject.should include(&quot;You're Invited&quot;)
    • last_email_sent.to.should include(user.email)
    • (...)
  • 14. Demo – a view spec page_builder/toolbox_nav_page.feature:151
        • high level given's and when's, then the then's
        • asserts flash, tabs, fields, buttons, links, icons, etc
    • Scenario: Controls for edit a download
    • Given I can edit an existing page in an existing project
    • When I go add content to the page
    • And I click the &quot;File download&quot; button
    • #And (show me)
    • Then I should see a Notice saying &quot;Content added&quot;
    • And the toolbox should be on the &quot;Edit selected&quot; tab
    • And the compose-view area should have a &quot;File&quot; file input for the Download
    • And the compose-view area should have a &quot;Upload File&quot; button posting to &quot;page/component/update&quot;
    • And the compose-view area should have a &quot;No file now, Upload later&quot; link to &quot;page/components/new&quot;
    • And the toolbox area should have a &quot;Title&quot; text input for the Download
    • And the toolbox area should have a &quot;Description&quot; textarea input for the Download
    • And the toolbox area should have a &quot;Save Changes&quot; button posting to &quot;page/component/update&quot;
    • And the toolbox area should have a &quot;Back to compose page&quot; link to &quot;page/components/new&quot;
    • And the toolbox area should have a &quot;Delete&quot; icon to &quot;page/component/nuke&quot;
    • And the toolbox area should have an &quot;Up&quot; icon to &quot;page/component/higher&quot;
  • 15. Demo – an epic story poetry_contest/submitter_adds_attachment.feature:88
    • Scenario: There are multiple submitters, with multiple submissions, with multiple attachments
    • Given a Poetry Submissions setup
    • And project has a two file upload fields
    • # ------
    • And there is a user with email &quot;shira@linowes.com&quot;
    • And the user is a Submitter member who has been Approved
    • When I browse to the project &quot;home&quot; page
    • And I log in as &quot;shira@linowes.com&quot;
    • And I click the &quot;Submit&quot; link
    • And I fill out and submit the Submission form with:
    • | field | value |
    • | poem | Mary had a little lamb |
    • | file upload | shira-poem.txt |
    • | image upload | shira.jpg |
    • Then a Poetry submission for me should be created
    • And the file &quot;shira-poem.txt&quot; should be uploaded
    • And the file &quot;shira.jpg&quot; should be uploaded
    • When I click the &quot;Submit&quot; link
    • And I fill out and submit the Submission form with:
    • | field | value |
    • | poem | Mary had a little lamb 2222|
    • | file upload | shira-poem2.doc |
    • | image upload | snow.jpg |
    • Then a Poetry submission for me should be created
    • And the file &quot;shira-poem2.doc&quot; should be uploaded
    • And the file &quot;snow.jpg&quot; should be uploaded
    • When I log out
    • # ------
    • Given a user with email &quot;steven@linowes.com&quot;
    • And the user is a Submitter member who has been Approved
    • When I browse to the project &quot;home&quot; page
    • And I log in as &quot;steven@linowes.com&quot;
    • And I click the &quot;Submit&quot; link
    • And I fill out and submit the Submission form with:
    • complex setup
    • testing uploads
    • using step tables
    • 45 steps!
  • 16. Closing Thoughts
    • requires time and thought about natural language and conventions
    • haven't integrated with browsers yet – selenium, etc
    • especially for javascript (unobtrusive, ftw!)
    • cap deploy:features -- ftw!