Cucumber: How I Slice It Jonathan Linowes Parkerhill Technology Group NH Ruby Group, January 15, 2009 Executable plain-tex...
Intro <ul><li>See http://www.slideshare.net/bkeepers/behavior-driven-development-with-cucumber-presentation </li></ul><ul>...
Uses <ul><li>Collaboration, brainstorming with customer </li></ul><ul><li>Specification, refinement of requirements </li><...
How I actually use it <ul><li>Talking to myself (planning) </li></ul><ul><li>Keep track of what I'm working on (outlining)...
When I use it <ul><li>written first, in true BDD tao </li></ul><ul><li>written simultaneously with code and specs </li></u...
Directories and files <ul><li>Rails app root/ </li></ul><ul><ul><li>features/ </li></ul></ul><ul><ul><ul><li>[feature set]...
Demo – simple clicking <ul><li>Feature: simple clicking </li></ul><ul><li>As someone interested in the Poetry Contest </li...
Given <ul><li>Given /^a Poetry (.*) setup$/ do |setup| </li></ul><ul><li>@account ||= create_account( 'test' ) </li></ul><...
When <ul><li>Using regexp conventions in matcher </li></ul><ul><li>Using quotes for named things </li></ul><ul><li>String#...
Then <ul><li>Using webrat for asserts </li></ul><ul><li>Matches keywords like 'link$/' or 'page$/' </li></ul><ul><li>Natur...
Utilities <ul><li>See  http://www.vaporbase.com/postings/Show_me_the_response   </li></ul><ul><li>Then /^the page html sho...
Demo – scenario outline membership/invite_reviewer.feature:41 (29) <ul><li>Runs once for each example </li></ul><ul><li>ma...
mailer_setup <ul><li># env.rb </li></ul><ul><li>def mailer_setup </li></ul><ul><li>ActionMailer::Base.delivery_method = :t...
Demo – a view spec page_builder/toolbox_nav_page.feature:151 <ul><ul><ul><li>high level given's and when's, then the then'...
Demo – an epic story poetry_contest/submitter_adds_attachment.feature:88 <ul><li>Scenario: There are multiple submitters, ...
Closing Thoughts <ul><li>requires time and thought about natural language and conventions </li></ul><ul><li>haven't integr...
Upcoming SlideShare
Loading in...5
×

Cucumber: How I Slice It

3,863

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

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,863
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
100
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Cucumber: How I Slice It

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

    Clipping is a handy way to collect important slides you want to go back to later.

×