Friday, February 4, 2011
@leshillFriday, February 4, 2011
Friday, February 4, 2011
Rocketeer #7Friday, February 4, 2011
Friday, February 4, 2011
We are hiring.                           http://pictureofhealth.comFriday, February 4, 2011
Cultivating                            Cucumber                           It is great food for thought!Friday, February 4,...
HappyFriday, February 4, 2011
Not so HappyFriday, February 4, 2011
Confident!                           And Happy!Friday, February 4, 2011
BackgroundFriday, February 4, 2011
Feature1 Feature: Design and Build an app using BDD2   In order to produce an app at low cost      and high speed3   As a ...
Scenario and Steps             Scenario: Description of what to testFriday, February 4, 2011
Scenario and Steps             Scenario: Description of what to test                     Given puts the system into a know...
Scenario and Steps             Scenario: Description of what to test                     Given puts the system into a know...
Scenario and Steps             Scenario: Description of what to test                     Given puts the system into a know...
Scenario and Steps             Scenario: Description of what to test                     Given puts the system into a know...
Step Definitions            def log(*args)              puts args.join(,)            end            When /^three (.*) mice...
Step Definitions            def log(*args)              puts args.join(,)            end            When /^three (.*) mice...
Step Definitions            def log(*args)              puts args.join(,)            end            When /^three (.*) mice...
Step Definitions            def log(*args)              puts args.join(,)            end            When /^three (.*) mice...
Step Definitions            def log(*args)              puts args.join(,)            end            When /^three (.*) mice...
Step Definitions            def log(*args)              puts args.join(,)            end            When /^three (.*) mice...
Step Definitions            def log(*args)              puts args.join(,)            end            When /^three (.*) mice...
HooksFriday, February 4, 2011
Around Hook                           Around do |scenario, block|                  2          puts "1st"                  ...
Around Hook  Scenario: How are the around hooks sequenced     When I runFriday, February 4, 2011
Around Hook  Scenario: How are the around hooks sequenced     When I run %wip Using the wip profile... Feature: Around hook...
Around Hook  Scenario: How are the around hooks sequenced     When I run %wip Using the wip profile... Feature: Around hook...
Around HookScenario: What happens when there is a failure  When I failFriday, February 4, 2011
Around HookScenario: What happens when there is a failure  When I fail % wip Feature: Around hook sequencing  @wip  Scenar...
Around HookScenario: What happens when there is a failure  When I fail % wip Feature: Around hook sequencing  @wip  Scenar...
HappyFriday, February 4, 2011
AfterStep Hook                           13 AfterStep do |scenario|                           14   puts "after_step"      ...
AfterStep Hook Scenario: What happens when there is a failure   When I run   And I fail               Scenario: What happe...
Not so HappyFriday, February 4, 2011
Global Hooks              # features/support/global.rb              my_heavy_object = HeavyObject.new           18 my_heav...
AfterConfiguration Hook   AfterConfiguration do |config|25   puts "Features in #{config.feature_dirs}"26 end Friday, Febru...
TagsFriday, February 4, 2011
Tags       @likes       Scenario: This scenario is tagged by likes         Given this scenario is tagged "@likes"         ...
Tags                           % cucumber --tags @likesFriday, February 4, 2011
Tags                           % cucumber --tags ~@likesFriday, February 4, 2011
Tags                           % cucumber --tags @likes,@ratingsFriday, February 4, 2011
Tags                           % cucumber --tags @likes --tags @ratingsFriday, February 4, 2011
Confident!                           And Happy!Friday, February 4, 2011
Tagged HooksFriday, February 4, 2011
Tagged Hooks                           1 Before(@given_user) do                           2   @user = "This is set"       ...
Tagged Hooks                           1 Before(@given_user) do                           2   @user = "This is set"       ...
World Object            def log(*args)              puts args.join(,)            end            When /^three (.*) mice$/ d...
World Object            def log(*args)              puts args.join(,)            end            When /^three (.*) mice$/ d...
World Object            module Log              def log(*args)                puts args.join(,)              end          ...
Tagged Hooks1 Feature: Using Before and After with tags2   In order to be more effective with cucumber3   As a cucumberist...
Tagged Hooks    Then /^the user is( not)? set$/ do |negated|      if negated        @user.should_not be      else        @...
Tagged Hooks    $ cucumber features/before_and_after_profile.feature    Using the default profile...    Feature: Using Befor...
HappyFriday, February 4, 2011
Not so HappyFriday, February 4, 2011
Tagged Hooks                 5 Before(@reviews,@likes) do                  6   puts "This is an OR"                  7 end...
Not so HappyFriday, February 4, 2011
Special TagsFriday, February 4, 2011
@wip   1 @wip   2 Feature: Resolving ambiguity with --guess   3   4   Scenario: Ambiguous step definitions   5      Given ...
@wip                           % cucumber -p wip                           % rake cucumber:wip                           %...
@wip<%rerun = File.file?(rerun.txt) ? IO.read(rerunrerun_opts = rerun.to_s.strip.empty? ? "--formatstd_opts = "--format #{...
@wip<%rerun = File.file?(rerun.txt) ? IO.read(rerunrerun_opts = rerun.to_s.strip.empty? ? "--formatstd_opts = "--format #{...
@wip  % wip  Using the wip profile...  Feature: Using the path helper   @wip   Scenario: Using a regex with the path helper...
Confident!                           And Happy!Friday, February 4, 2011
@no-txn   @no-txn   Scenario: Sending a message without pusher     Given @philip_jay_fry signs in with Twitter     And I s...
@javascript @javascript @pusher Scenario: Starting a conversation with Pusher   Given @philip_jay_fry signs in with Twitte...
HappyFriday, February 4, 2011
Using path_toFriday, February 4, 2011
path_to            Scenario: Context is king              Given the following movie:                | title | Gone with th...
path_to            Scenario: Context is king              Given the following movie:                | title | Gone with th...
path_to         When /^(?:|I )am on (.+)$/ do |page_name|           visit path_to(page_name)         end         When /^(?...
path_to         When /^(?:|I )am on (.+)$/ do |page_name|           visit path_to(page_name)         end         When /^(?...
path_to         When /^(?:|I )am on (.+)$/ do |page_name|           visit path_to(page_name)         end         When /^(?...
path_to         When /^(?:|I )am on (.+)$/ do |page_name|           visit path_to(page_name)         end         When /^(?...
path_to         When /^(?:|I )am on (.+)$/ do |page_name|           visit path_to(page_name)         end         When /^(?...
path_tomodule NavigationHelpers  def path_to(page_name)    case page_name    when /the homes?page/      /    else      beg...
path_tomodule NavigationHelpers  def path_to(page_name)    case page_name    when /the homes?page/      /    else      beg...
path_tomodule NavigationHelpers  def path_to(page_name)    case page_name    when /the homes?page/      /    else      beg...
path_tomodule NavigationHelpers  def path_to(page_name)    case page_name    when /the homes?page/      /    else      beg...
path_to                           Scenario: Using a regex with the path helper                             Given the follo...
path_to                           Scenario: Using a regex with the path helper                             Given the follo...
path_to                           Scenario: Using a regex with the path helper                             Given the follo...
path_to                           Scenario: Using a regex with the path helper                             Given the follo...
Confident!                           And Happy!Friday, February 4, 2011
Building A FactoryFriday, February 4, 2011
SpecificScenario: Domain specific, totally opaque  Given a movie  When I go to the home page  Then I should see "Gone with...
SpecificScenario: Domain specific, totally opaque  Given a movie  When I go to the home page  Then I should see "Gone with...
SpecificScenario: Domain specific, totally opaque  Given a movie  When I go to the home page  Then I should see "Gone with...
SpecificScenario: Domain specific, totally opaque  Given a movie  When I go to the home page  Then I should see "Gone with...
Imperative                       Scenario: Way too granular                         Given a movie                         ...
Imperative                       Scenario: Way too granular                         Given a movie                         ...
Imperative                       Scenario: Way too granular                         Given a movie                         ...
Too much like Code           Scenario: Too much like code             Given a movie exists with { "title" => "Gone with th...
Too much like Code           Scenario: Too much like code             Given a movie exists with { "title" => "Gone with th...
Too much like Code           Scenario: Too much like code             Given a movie exists with { "title" => "Gone with th...
Too much like Code           Scenario: Too much like code             Given a movie exists with { "title" => "Gone with th...
Not so HappyFriday, February 4, 2011
Cleaned UpScenario: Pickle  Given a movie exists with title: "Gone with the wind", year: "1939"  When I go to the home pag...
Cleaned UpScenario: Pickle  Given a movie exists with title: "Gone with the wind", year: "1939"  When I go to the home pag...
Generic Factory StepScenario: Generic factory step  Given the following movie:    | title | Gone with the wind |    | year...
Generic Factory StepScenario: Generic factory step  Given the following movie:    | title | Gone with the wind |    | year...
Using Tables                           ruby-1.9.2-p0 :001 > table                            =>                           ...
Using Tables                           ruby-1.9.2-p0 :001 > table                            =>                           ...
Using Tables                           ruby-1.9.2-p0 :001 > table                            =>                           ...
Using Tables                           ruby-1.9.2-p0 :001 > table                            =>                           ...
Using Tables                           ruby-1.9.2-p0 :001 > table                            =>                           ...
Generic Factory Step     module FabricationMethods       def create_from_table(model_name, table, extra = {})         fabr...
Generic Factory Step     module FabricationMethods       def create_from_table(model_name, table, extra = {})         fabr...
Generic Factory Step     module FabricationMethods       def create_from_table(model_name, table, extra = {})         fabr...
Generic Factory Step     module FabricationMethods       def create_from_table(model_name, table, extra = {})         fabr...
Generic Factory Step     module FabricationMethods       def create_from_table(model_name, table, extra = {})         fabr...
Easy Relationships                       Scenario: Has/Belongs to Relationships                         Given the followin...
Easy Relationships                       Scenario: Has/Belongs to Relationships                         Given the followin...
Easy Relationships                       Scenario: Has/Belongs to Relationships                         Given the followin...
Easy Relationships                       Scenario: Has/Belongs to Relationships                         Given the followin...
Confident!                           And Happy!Friday, February 4, 2011
TransformsFriday, February 4, 2011
Step Argument Transform               Scenario: Step argument transforms                 Given the following movie:       ...
Step Argument Transform               Scenario: Step argument transforms                 Given the following movie:       ...
Step Argument Transform                When /^that movie has been liked (d+) times$/ do |count|                  count.to_...
Step Argument Transform                When /^that movie has been liked (d+) times$/ do |count|                  count.to_...
Step Argument Transform         # Convert a or an to the integer value 1         Transform /^(an?|-?d+)$/ do |amount|     ...
Step Argument Transform         # Convert a or an to the integer value 1         Transform /^(an?|-?d+)$/ do |amount|     ...
Step Argument Transform         # Convert a or an to the integer value 1         Transform /^(an?|-?d+)$/ do |amount|     ...
Step Argument Transform         # Convert a or an to the integer value 1         Transform /^(an?|-?d+)$/ do |amount|     ...
Not so HappyFriday, February 4, 2011
Step Argument Transforms          Scenario: Context is king            Given the following movie:              | title | G...
Step Argument Transforms          Scenario: Context is king            Given the following movie:              | title | G...
Step Argument Transforms         Transform /^movie "([^"]+)"$/ do |title|           Movie.find_by_title(title)         end...
Step Argument Transforms         Transform /^movie "([^"]+)"$/ do |title|           Movie.find_by_title(title)         end...
Step Argument Transforms         Transform /^movie "([^"]+)"$/ do |title|           Movie.find_by_title(title)         end...
Step Argument Transforms         Transform /^movie "([^"]+)"$/ do |title|           Movie.find_by_title(title)         end...
Confident!                           And Happy!Friday, February 4, 2011
Table Transforms       Transform /^table:name,actor$/ do |table|         table.map_column!(:actor) do |actor_name|        ...
Table Transforms       Transform /^table:name,actor$/ do |table|         table.map_column!(:actor) do |actor_name|        ...
Table Transforms       Transform /^table:name,actor$/ do |table|         table.map_column!(:actor) do |actor_name|        ...
Table Transforms       Transform /^table:name,actor$/ do |table|         table.map_column!(:actor) do |actor_name|        ...
Table Transforms  Scenario: Relationships using step transforms to transform the table    Given the following movie:      ...
Table Transforms  Scenario: Relationships using step transforms to transform the table    Given the following movie:      ...
Table Transforms      Transform /^table:name,actor$/ do |table|        table.map_column!(:actor) do |actor_name|          ...
HappyFriday, February 4, 2011
Not so HappyFriday, February 4, 2011
Better UI ScopesFriday, February 4, 2011
Shipped Web StepsScenario: Viewing a group  When @philip_jay_fry signs in  And I go to the “Planet Express” group  Then I ...
Shipped Web StepsScenario: Viewing a group  When @philip_jay_fry signs in  And I go to the “Planet Express” group  Then I ...
Shipped Web Steps     module WithinHelpers     13def with_scope(locator)     14  locator ? within(locator) { yield } : yie...
Shipped Web Steps     module WithinHelpers     13def with_scope(locator)     14  locator ? within(locator) { yield } : yie...
Shipped Web Steps     module WithinHelpers     13def with_scope(locator)     14  locator ? within(locator) { yield } : yie...
Shipped Web Steps     module WithinHelpers     13def with_scope(locator)     14  locator ? within(locator) { yield } : yie...
Shipped Web Steps     module WithinHelpers     13def with_scope(locator)     14  locator ? within(locator) { yield } : yie...
Not so HappyFriday, February 4, 2011
Removing CSS/XPath      Scenario: Simple and Direct        Given the following movie:          | title | Gone with the win...
Removing CSS/XPath      Scenario: Simple and Direct        Given the following movie:          | title | Gone with the win...
Removing CSS/XPath      Scenario: Simple and Direct        Given the following movie:          | title | Gone with the win...
Removing CSS/XPath      Scenario: Simple and Direct        Given the following movie:          | title | Gone with the win...
Removing CSS/XPath      Scenario: Simple and Direct        Given the following movie:          | title | Gone with the win...
Removing CSS/XPath      Scenario: Simple and Direct        Given the following movie:          | title | Gone with the win...
Removing CSS/XPath      Scenario: Simple and Direct        Given the following movie:          | title | Gone with the win...
HappyFriday, February 4, 2011
Removing CSS/XPath Scenario: Using selector_for   Given the following movie:     | title | Gone with the wind |     | year...
Removing CSS/XPath Scenario: Using selector_for   Given the following movie:     | title | Gone with the wind |     | year...
Removing CSS/XPath Scenario: Using selector_for   Given the following movie:     | title | Gone with the wind |     | year...
Removing CSS/XPath Scenario: Using selector_for   Given the following movie:     | title | Gone with the wind |     | year...
Removing CSS/XPath Scenario: Using selector_for   Given the following movie:     | title | Gone with the wind |     | year...
selector_for module HtmlSelectorsHelper   def selector_for(scope)     case scope     when /the body/       "html > body"  ...
HappyFriday, February 4, 2011
Persistent ScopesScenario: Persistent scoping  Given the following movies:    | title              | year |    | Gone with...
Persistent ScopesScenario: Persistent scoping  Given the following movies:    | title              | year |    | Gone with...
Persistent Scopes                   module PersistentScope                     def persistent_scope(scope = nil)          ...
Persistent Scopes                   module PersistentScope                     def persistent_scope(scope = nil)          ...
Persistent Scopes                   module PersistentScope                     def persistent_scope(scope = nil)          ...
Persistent Scopes                   module PersistentScope                     def persistent_scope(scope = nil)          ...
Persistent Scopes                   module PersistentScope                     def persistent_scope(scope = nil)          ...
Confident!                           And Happy!Friday, February 4, 2011
Write Better                            ScenariosFriday, February 4, 2011
ImperativeScenario: Successful animal creation  Given Im on the animal creation page  When I fill in Name with Alligator  ...
Declarative                 Scenario: Successful animal creation                   Given Im on the animal creation page   ...
UX                    Feature: Visitor uses advertiser carousel                      Background:                        Gi...
Outside InFriday, February 4, 2011
Confident!                           And Happy!Friday, February 4, 2011
Cucumber:                           The Bad PartsFriday, February 4, 2011
Not so HappyFriday, February 4, 2011
Cucumber:                           The Good PartFriday, February 4, 2011
HappyFriday, February 4, 2011
Thank you!Friday, February 4, 2011
Upcoming SlideShare
Loading in …5
×

Cultivating Cucumber

2,759 views

Published on

Tips, Techniques, and Opinions on being more effective with Cucumber

Published in: Technology, Business
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,759
On SlideShare
0
From Embeds
0
Number of Embeds
13
Actions
Shares
0
Downloads
47
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Cultivating Cucumber

  1. 1. Friday, February 4, 2011
  2. 2. @leshillFriday, February 4, 2011
  3. 3. Friday, February 4, 2011
  4. 4. Rocketeer #7Friday, February 4, 2011
  5. 5. Friday, February 4, 2011
  6. 6. We are hiring. http://pictureofhealth.comFriday, February 4, 2011
  7. 7. Cultivating Cucumber It is great food for thought!Friday, February 4, 2011
  8. 8. HappyFriday, February 4, 2011
  9. 9. Not so HappyFriday, February 4, 2011
  10. 10. Confident! And Happy!Friday, February 4, 2011
  11. 11. BackgroundFriday, February 4, 2011
  12. 12. Feature1 Feature: Design and Build an app using BDD2 In order to produce an app at low cost and high speed3 As a developer4 I should employ Rails with CucumberFriday, February 4, 2011
  13. 13. Scenario and Steps Scenario: Description of what to testFriday, February 4, 2011
  14. 14. Scenario and Steps Scenario: Description of what to test Given puts the system into a known stateFriday, February 4, 2011
  15. 15. Scenario and Steps Scenario: Description of what to test Given puts the system into a known state When specifies the user’s actionsFriday, February 4, 2011
  16. 16. Scenario and Steps Scenario: Description of what to test Given puts the system into a known state When specifies the user’s actions Then we can observe the outcomeFriday, February 4, 2011
  17. 17. Scenario and Steps Scenario: Description of what to test Given puts the system into a known state Given specifies the user’s actions Given we can observe the outcomeFriday, February 4, 2011
  18. 18. Step Definitions def log(*args) puts args.join(,) end When /^three (.*) mice$/ do |disability| log disability end When /^three blind (.*)$/ do |animal| log animal endFriday, February 4, 2011
  19. 19. Step Definitions def log(*args) puts args.join(,) end When /^three (.*) mice$/ do |disability| log disability end When /^three blind (.*)$/ do |animal| log animal endFriday, February 4, 2011
  20. 20. Step Definitions def log(*args) puts args.join(,) end When /^three (.*) mice$/ do |disability| log disability end When /^three blind (.*)$/ do |animal| log animal endFriday, February 4, 2011
  21. 21. Step Definitions def log(*args) puts args.join(,) end When /^three (.*) mice$/ do |disability| log disability end When /^three blind (.*)$/ do |animal| log animal endFriday, February 4, 2011
  22. 22. Step Definitions def log(*args) puts args.join(,) end When /^three (.*) mice$/ do |disability| log disability end When /^three blind (.*)$/ do |animal| log animal endFriday, February 4, 2011
  23. 23. Step Definitions def log(*args) puts args.join(,) end When /^three (.*) mice$/ do |disability| log disability end When /^three blind (.*)$/ do |animal| log animal endFriday, February 4, 2011
  24. 24. Step Definitions def log(*args) puts args.join(,) end When /^three (.*) mice$/ do |disability| log disability end When /^three blind (.*)$/ do |animal| log animal endFriday, February 4, 2011
  25. 25. HooksFriday, February 4, 2011
  26. 26. Around Hook Around do |scenario, block| 2 puts "1st" 3 block.call 4 puts "1st" 5 end 6 7 Around do |scenario, block| 8 puts "2nd" 9 block.call 10 puts "2nd" 11 endFriday, February 4, 2011
  27. 27. Around Hook Scenario: How are the around hooks sequenced When I runFriday, February 4, 2011
  28. 28. Around Hook Scenario: How are the around hooks sequenced When I run %wip Using the wip profile... Feature: Around hook sequencing @wip Scenario: How are the around hooks sequenced # features/around_hook.feature:7 1st 2nd When I run # features/step_definitions/run_steps.rb:5 2nd 1st 1 scenario (1 passed) 1 step (1 passed) 0m1.569s The --wip switch was used, so I didnt expect anything to pass. These scenarios passed:Friday, February 4, 2011
  29. 29. Around Hook Scenario: How are the around hooks sequenced When I run %wip Using the wip profile... Feature: Around hook sequencing @wip Scenario: How are the around hooks sequenced # features/around_hook.feature:7 1st 2nd When I run # features/step_definitions/run_steps.rb:5 2nd 1st 1 scenario (1 passed) 1 step (1 passed) 0m1.569s The --wip switch was used, so I didnt expect anything to pass. These scenarios passed:Friday, February 4, 2011
  30. 30. Around HookScenario: What happens when there is a failure When I failFriday, February 4, 2011
  31. 31. Around HookScenario: What happens when there is a failure When I fail % wip Feature: Around hook sequencing @wip Scenario: What happens when there is a failure # features/around_hook.feature:10 1st 2nd When I fail # features/step_definitions/run_steps.rb:9 (RuntimeError) ./features/step_definitions/run_steps.rb:10:in `/^I fail$/ features/around_hook.feature:11:in `When I fail 2nd 1st Failing Scenarios: cucumber -p wip features/around_hook.feature:10 # Scenario: What happens when there is a failure 1 scenario (1 failed) 1 step (1 failed) 0m1.522s The --wip switch was used, so the failures were expected. All is good.Friday, February 4, 2011
  32. 32. Around HookScenario: What happens when there is a failure When I fail % wip Feature: Around hook sequencing @wip Scenario: What happens when there is a failure # features/around_hook.feature:10 1st 2nd When I fail # features/step_definitions/run_steps.rb:9 (RuntimeError) ./features/step_definitions/run_steps.rb:10:in `/^I fail$/ features/around_hook.feature:11:in `When I fail 2nd 1st Failing Scenarios: cucumber -p wip features/around_hook.feature:10 # Scenario: What happens when there is a failure 1 scenario (1 failed) 1 step (1 failed) 0m1.522s The --wip switch was used, so the failures were expected. All is good.Friday, February 4, 2011
  33. 33. HappyFriday, February 4, 2011
  34. 34. AfterStep Hook 13 AfterStep do |scenario| 14 puts "after_step" 15 endFriday, February 4, 2011
  35. 35. AfterStep Hook Scenario: What happens when there is a failure When I run And I fail Scenario: What happens when there is a failure # features/after_step_hook.feature:13 after_step When I run # features/step_definitions/run_steps.rb:5 And I fail # features/step_definitions/run_steps.rb:9 (RuntimeError) ./features/step_definitions/run_steps.rb:10:in `/^I fail$/ features/after_step_hook.feature:15:in `And I failFriday, February 4, 2011
  36. 36. Not so HappyFriday, February 4, 2011
  37. 37. Global Hooks # features/support/global.rb my_heavy_object = HeavyObject.new 18 my_heavy_object.do_it 19 20 at_exit do 21 my_heavy_object.undo_it 22 endFriday, February 4, 2011
  38. 38. AfterConfiguration Hook AfterConfiguration do |config|25 puts "Features in #{config.feature_dirs}"26 end Friday, February 4, 2011
  39. 39. TagsFriday, February 4, 2011
  40. 40. Tags @likes Scenario: This scenario is tagged by likes Given this scenario is tagged "@likes" Then the "likes" tag is on the scenarioFriday, February 4, 2011
  41. 41. Tags % cucumber --tags @likesFriday, February 4, 2011
  42. 42. Tags % cucumber --tags ~@likesFriday, February 4, 2011
  43. 43. Tags % cucumber --tags @likes,@ratingsFriday, February 4, 2011
  44. 44. Tags % cucumber --tags @likes --tags @ratingsFriday, February 4, 2011
  45. 45. Confident! And Happy!Friday, February 4, 2011
  46. 46. Tagged HooksFriday, February 4, 2011
  47. 47. Tagged Hooks 1 Before(@given_user) do 2 @user = "This is set" 3 endFriday, February 4, 2011
  48. 48. Tagged Hooks 1 Before(@given_user) do 2 @user = "This is set" 3 endFriday, February 4, 2011
  49. 49. World Object def log(*args) puts args.join(,) end When /^three (.*) mice$/ do |disability| log disability end When /^three blind (.*)$/ do |animal| log animal endFriday, February 4, 2011
  50. 50. World Object def log(*args) puts args.join(,) end When /^three (.*) mice$/ do |disability| log disability end When /^three blind (.*)$/ do |animal| log animal endFriday, February 4, 2011
  51. 51. World Object module Log def log(*args) puts args.join(,) end end World(Log) When /^three (.*) mice$/ do |disability| log disability end When /^three blind (.*)$/ do |animal| log animal endFriday, February 4, 2011
  52. 52. Tagged Hooks1 Feature: Using Before and After with tags2 In order to be more effective with cucumber3 As a cucumberist4 You can use Before and After with tags!56 Scenario: Does not want the before step run7 Then the user is not set89 @given_user0 Scenario: Does want the before step run1 Then the user is set Friday, February 4, 2011
  53. 53. Tagged Hooks Then /^the user is( not)? set$/ do |negated| if negated @user.should_not be else @user.should be end endFriday, February 4, 2011
  54. 54. Tagged Hooks $ cucumber features/before_and_after_profile.feature Using the default profile... Feature: Using Before and After with tags In order to be more effective with cucumber As a cucumberist You can use Before and After with tags! Scenario: This scenario does not want the before step run # features/before_and_after_profile.featur Then the user is not set # features/step_definitions/user_steps.rb:1 @given_user Scenario: This scenario wants something set before it runs # features/before_and_after_profile.featur Then the user is set # features/step_definitions/user_steps.rb:1 2 scenarios (2 passed) 2 steps (2 passed) 0m1.525sFriday, February 4, 2011
  55. 55. HappyFriday, February 4, 2011
  56. 56. Not so HappyFriday, February 4, 2011
  57. 57. Tagged Hooks 5 Before(@reviews,@likes) do 6 puts "This is an OR" 7 end 8 9 Before (@reviews, @likes) do 10 puts "This is an AND" 11 end 12 13 Before (~@reviews) do 14 puts "This is NOT" 15 endFriday, February 4, 2011
  58. 58. Not so HappyFriday, February 4, 2011
  59. 59. Special TagsFriday, February 4, 2011
  60. 60. @wip 1 @wip 2 Feature: Resolving ambiguity with --guess 3 4 Scenario: Ambiguous step definitions 5 Given three blind miceFriday, February 4, 2011
  61. 61. @wip % cucumber -p wip % rake cucumber:wip % alias wip=‘cucumber -p wip’Friday, February 4, 2011
  62. 62. @wip<%rerun = File.file?(rerun.txt) ? IO.read(rerunrerun_opts = rerun.to_s.strip.empty? ? "--formatstd_opts = "--format #{ENV[CUCUMBER_FORMAT] ||%>default: <%= std_opts %> featureswip: --tags @wip:3 --wip featuresrerun: <%= rerun_opts %> --format rerun --out reFriday, February 4, 2011
  63. 63. @wip<%rerun = File.file?(rerun.txt) ? IO.read(rerunrerun_opts = rerun.to_s.strip.empty? ? "--formatstd_opts = "--format #{ENV[CUCUMBER_FORMAT] ||%>default: <%= std_opts %> featureswip: --tags @wip:3 --wip featuresrerun: <%= rerun_opts %> --format rerun --out reFriday, February 4, 2011
  64. 64. @wip % wip Using the wip profile... Feature: Using the path helper @wip Scenario: Using a regex with the path helper # features/paths.feature:7 Given the following movie: # features/step_definitions/fabrication_steps.rb:37 | title | Gone with the wind | | year | 1939 | When I go to the "Gone with the wind" movie page # features/step_definitions/web_steps.rb:30 Then I should see "Gone with the wind (1939)" # features/step_definitions/web_steps.rb:114 expected #has_content?("Gone with the wind (1939)") to return true, got false (RSpec::Expectations::ExpectationNotMetError) features/paths.feature:12:in `Then I should see "Gone with the wind (1939)" Failing Scenarios: cucumber -p wip features/paths.feature:7 # Scenario: Using a regex with the path helper 1 scenario (1 failed) 3 steps (1 failed, 2 passed) 0m2.245s The --wip switch was used, so the failures were expected. All is good.Friday, February 4, 2011
  65. 65. Confident! And Happy!Friday, February 4, 2011
  66. 66. @no-txn @no-txn Scenario: Sending a message without pusher Given @philip_jay_fry signs in with Twitter And I start a conversation with @t_leela When I reply with "Hi Leela" Then the source is the browserFriday, February 4, 2011
  67. 67. @javascript @javascript @pusher Scenario: Starting a conversation with Pusher Given @philip_jay_fry signs in with Twitter When the browser has subscribed to Pusher And I start a conversation with"@t_leela" Then the source is pusher in the browserFriday, February 4, 2011
  68. 68. HappyFriday, February 4, 2011
  69. 69. Using path_toFriday, February 4, 2011
  70. 70. path_to Scenario: Context is king Given the following movie: | title | Gone with the wind | | year | 1939 | When the movie "Gone with the wind" has been liked 5 times And I go to ‘/’ Then I should see "5 likes"Friday, February 4, 2011
  71. 71. path_to Scenario: Context is king Given the following movie: | title | Gone with the wind | | year | 1939 | When the movie "Gone with the wind" has been liked 5 times And I go to ‘/’ Then I should see "5 likes" Scenario: Context is king Given the following movie: | title | Gone with the wind | | year | 1939 | When the movie "Gone with the wind" has been liked 5 times And I go to the home page Then I should see "5 likes"Friday, February 4, 2011
  72. 72. path_to When /^(?:|I )am on (.+)$/ do |page_name| visit path_to(page_name) end When /^(?:|I )go to (.+)$/ do |page_name| visit path_to(page_name) endFriday, February 4, 2011
  73. 73. path_to When /^(?:|I )am on (.+)$/ do |page_name| visit path_to(page_name) end When /^(?:|I )go to (.+)$/ do |page_name| visit path_to(page_name) endFriday, February 4, 2011
  74. 74. path_to When /^(?:|I )am on (.+)$/ do |page_name| visit path_to(page_name) end When /^(?:|I )go to (.+)$/ do |page_name| visit path_to(page_name) endFriday, February 4, 2011
  75. 75. path_to When /^(?:|I )am on (.+)$/ do |page_name| visit path_to(page_name) end When /^(?:|I )go to (.+)$/ do |page_name| visit path_to(page_name) endFriday, February 4, 2011
  76. 76. path_to When /^(?:|I )am on (.+)$/ do |page_name| visit path_to(page_name) end When /^(?:|I )go to (.+)$/ do |page_name| visit path_to(page_name) endFriday, February 4, 2011
  77. 77. path_tomodule NavigationHelpers def path_to(page_name) case page_name when /the homes?page/ / else begin page_name =~ /the (.*) page/ path_components = $1.split(/s+/) self.send(path_components.push(path).join(_).to_sym) rescue Object => e raise "Cant find mapping from "#{page_name}" to a path.n" + "Now, go and add a mapping in #{__FILE__}" end end endendWorld(NavigationHelpers)Friday, February 4, 2011
  78. 78. path_tomodule NavigationHelpers def path_to(page_name) case page_name when /the homes?page/ / else begin page_name =~ /the (.*) page/ path_components = $1.split(/s+/) self.send(path_components.push(path).join(_).to_sym) rescue Object => e raise "Cant find mapping from "#{page_name}" to a path.n" + "Now, go and add a mapping in #{__FILE__}" end end endendWorld(NavigationHelpers)Friday, February 4, 2011
  79. 79. path_tomodule NavigationHelpers def path_to(page_name) case page_name when /the homes?page/ / else begin page_name =~ /the (.*) page/ path_components = $1.split(/s+/) self.send(path_components.push(path).join(_).to_sym) rescue Object => e raise "Cant find mapping from "#{page_name}" to a path.n" + "Now, go and add a mapping in #{__FILE__}" end end endendWorld(NavigationHelpers)Friday, February 4, 2011
  80. 80. path_tomodule NavigationHelpers def path_to(page_name) case page_name when /the homes?page/ / else begin page_name =~ /the (.*) page/ path_components = $1.split(/s+/) self.send(path_components.push(path).join(_).to_sym) rescue Object => e raise "Cant find mapping from "#{page_name}" to a path.n" + "Now, go and add a mapping in #{__FILE__}" end end endendWorld(NavigationHelpers)Friday, February 4, 2011
  81. 81. path_to Scenario: Using a regex with the path helper Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the "Gone with the wind" movie page Then I should see "Gone with the wind (1939)"Friday, February 4, 2011
  82. 82. path_to Scenario: Using a regex with the path helper Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the "Gone with the wind" movie page Then I should see "Gone with the wind (1939)"Friday, February 4, 2011
  83. 83. path_to Scenario: Using a regex with the path helper Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the "Gone with the wind" movie page Then I should see "Gone with the wind (1939)" when /the "([^"]+)" movie page/ movie_path(Movie.find_by_title($1))Friday, February 4, 2011
  84. 84. path_to Scenario: Using a regex with the path helper Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the "Gone with the wind" movie page Then I should see "Gone with the wind (1939)" when /the "([^"]+)" movie page/ movie_path(Movie.find_by_title($1))Friday, February 4, 2011
  85. 85. Confident! And Happy!Friday, February 4, 2011
  86. 86. Building A FactoryFriday, February 4, 2011
  87. 87. SpecificScenario: Domain specific, totally opaque Given a movie When I go to the home page Then I should see "Gone with the wind (1939)"Friday, February 4, 2011
  88. 88. SpecificScenario: Domain specific, totally opaque Given a movie When I go to the home page Then I should see "Gone with the wind (1939)" When /^a movie$/ do Movie.create(title: Gone with the wind, year: 1939) endFriday, February 4, 2011
  89. 89. SpecificScenario: Domain specific, totally opaque Given a movie When I go to the home page Then I should see "Gone with the wind (1939)" When /^a movie$/ do Movie.create(title: Gone with the wind, year: 1939) endFriday, February 4, 2011
  90. 90. SpecificScenario: Domain specific, totally opaque Given a movie When I go to the home page Then I should see "Gone with the wind (1939)" When /^a movie$/ do Movie.create(title: Gone with the wind, year: 1939) endFriday, February 4, 2011
  91. 91. Imperative Scenario: Way too granular Given a movie And I set the movies title to "Gone with the wind" And I set the movies year to "1939" And I save the movie When I go to the home page Then I should see "Gone with the wind (1939)"Friday, February 4, 2011
  92. 92. Imperative Scenario: Way too granular Given a movie And I set the movies title to "Gone with the wind" And I set the movies year to "1939" And I save the movie When I go to the home page Then I should see "Gone with the wind (1939)"Friday, February 4, 2011
  93. 93. Imperative Scenario: Way too granular Given a movie And I set the movies title to "Gone with the wind" And I set the movies year to "1939" And I save the movie When I go to the home page Then I should see "Gone with the wind (1939)"Friday, February 4, 2011
  94. 94. Too much like Code Scenario: Too much like code Given a movie exists with { "title" => "Gone with the wind", "year" => "1939" } When I go to the home page Then I should see "Gone with the wind (1939)"Friday, February 4, 2011
  95. 95. Too much like Code Scenario: Too much like code Given a movie exists with { "title" => "Gone with the wind", "year" => "1939" } When I go to the home page Then I should see "Gone with the wind (1939)" When /^a (.+) exists with ({.+})$/ do |model_name, attributes| model = dehumanize(model_name) model.create(eval(attributes)) endFriday, February 4, 2011
  96. 96. Too much like Code Scenario: Too much like code Given a movie exists with { "title" => "Gone with the wind", "year" => "1939" } When I go to the home page Then I should see "Gone with the wind (1939)" When /^a (.+) exists with ({.+})$/ do |model_name, attributes| model = dehumanize(model_name) model.create(eval(attributes)) end Yikes!Friday, February 4, 2011
  97. 97. Too much like Code Scenario: Too much like code Given a movie exists with { "title" => "Gone with the wind", "year" => "1939" } When I go to the home page Then I should see "Gone with the wind (1939)" ` When /^a (.+) exists with ({.+})$/ do |model_name, attributes| model = dehumanize(model_name) model.create(eval(attributes)) endFriday, February 4, 2011
  98. 98. Not so HappyFriday, February 4, 2011
  99. 99. Cleaned UpScenario: Pickle Given a movie exists with title: "Gone with the wind", year: "1939" When I go to the home page Then I should see "Gone with the wind (1939)"Friday, February 4, 2011
  100. 100. Cleaned UpScenario: Pickle Given a movie exists with title: "Gone with the wind", year: "1939" When I go to the home page Then I should see "Gone with the wind (1939)"Friday, February 4, 2011
  101. 101. Generic Factory StepScenario: Generic factory step Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)"Friday, February 4, 2011
  102. 102. Generic Factory StepScenario: Generic factory step Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)"Friday, February 4, 2011
  103. 103. Using Tables ruby-1.9.2-p0 :001 > table => | title | year | | Gone with the wind | 1939 | ruby-1.9.2-p0 :002 > table.headers => ["title", "year"] ruby-1.9.2-p0 :003 > table.rows => [["Gone with the wind", "1939"]] ruby-1.9.2-p0 :004 > table.hashes => [{"title"=>"Gone with the wind", "year"=>"1939"}] ruby-1.9.2-p0 :005 > table.rows_hash => {"title"=>"year", "Gone with the wind"=>"1939"}Friday, February 4, 2011
  104. 104. Using Tables ruby-1.9.2-p0 :001 > table => | title | year | | Gone with the wind | 1939 | ruby-1.9.2-p0 :002 > table.headers => ["title", "year"] ruby-1.9.2-p0 :003 > table.rows => [["Gone with the wind", "1939"]] ruby-1.9.2-p0 :004 > table.hashes => [{"title"=>"Gone with the wind", "year"=>"1939"}] ruby-1.9.2-p0 :005 > table.rows_hash => {"title"=>"year", "Gone with the wind"=>"1939"}Friday, February 4, 2011
  105. 105. Using Tables ruby-1.9.2-p0 :001 > table => | title | year | | Gone with the wind | 1939 | ruby-1.9.2-p0 :002 > table.headers => ["title", "year"] ruby-1.9.2-p0 :003 > table.rows => [["Gone with the wind", "1939"]] ruby-1.9.2-p0 :004 > table.hashes => [{"title"=>"Gone with the wind", "year"=>"1939"}] ruby-1.9.2-p0 :005 > table.rows_hash => {"title"=>"year", "Gone with the wind"=>"1939"}Friday, February 4, 2011
  106. 106. Using Tables ruby-1.9.2-p0 :001 > table => | title | year | | Gone with the wind | 1939 | ruby-1.9.2-p0 :002 > table.headers => ["title", "year"] ruby-1.9.2-p0 :003 > table.rows => [["Gone with the wind", "1939"]] ruby-1.9.2-p0 :004 > table.hashes => [{"title"=>"Gone with the wind", "year"=>"1939"}] ruby-1.9.2-p0 :005 > table.rows_hash => {"title"=>"year", "Gone with the wind"=>"1939"}Friday, February 4, 2011
  107. 107. Using Tables ruby-1.9.2-p0 :001 > table => | title | year | | Gone with the wind | 1939 | ruby-1.9.2-p0 :002 > table.headers => ["title", "year"] ruby-1.9.2-p0 :003 > table.rows => [["Gone with the wind", "1939"]] ruby-1.9.2-p0 :004 > table.hashes => [{"title"=>"Gone with the wind", "year"=>"1939"}] ruby-1.9.2-p0 :005 > table.rows_hash => {"title"=>"year", "Gone with the wind"=>"1939"}Friday, February 4, 2011
  108. 108. Generic Factory Step module FabricationMethods def create_from_table(model_name, table, extra = {}) fabricator_name = generate_fabricator_name(model_name) is_singular = model_name.to_s.singularize == model_name.to_s hashes = is_singular ? [table.rows_hash] : table.hashes @they = hashes.map do |hash| hash = hash.merge(extra).inject({}) {|h,(k,v)| h.update(k.gsub(/W+/,_).to_sym => v) Fabricate(fabricator_name, hash) end if is_singular @it = @they.last instance_variable_set("@#{fabricator_name}", @it) end end def generate_fabricator_name(model_name) model_name.gsub(/W+/, _).downcase.singularize.to_sym end end World(FabricationMethods) When /^the following ([^"]*):$/ do |model_name, table| create_from_table(model_name, table) endFriday, February 4, 2011
  109. 109. Generic Factory Step module FabricationMethods def create_from_table(model_name, table, extra = {}) fabricator_name = generate_fabricator_name(model_name) is_singular = model_name.to_s.singularize == model_name.to_s hashes = is_singular ? [table.rows_hash] : table.hashes @they = hashes.map do |hash| hash = hash.merge(extra).inject({}) {|h,(k,v)| h.update(k.gsub(/W+/,_).to_sym => v) Fabricate(fabricator_name, hash) end if is_singular @it = @they.last instance_variable_set("@#{fabricator_name}", @it) end end def generate_fabricator_name(model_name) model_name.gsub(/W+/, _).downcase.singularize.to_sym end end World(FabricationMethods) When /^the following ([^"]*):$/ do |model_name, table| create_from_table(model_name, table) endFriday, February 4, 2011
  110. 110. Generic Factory Step module FabricationMethods def create_from_table(model_name, table, extra = {}) fabricator_name = generate_fabricator_name(model_name) is_singular = model_name.to_s.singularize == model_name.to_s hashes = is_singular ? [table.rows_hash] : table.hashes @they = hashes.map do |hash| hash = hash.merge(extra).inject({}) {|h,(k,v)| h.update(k.gsub(/W+/,_).to_sym => v) Fabricate(fabricator_name, hash) end if is_singular @it = @they.last instance_variable_set("@#{fabricator_name}", @it) end end def generate_fabricator_name(model_name) model_name.gsub(/W+/, _).downcase.singularize.to_sym end end World(FabricationMethods) When /^the following ([^"]*):$/ do |model_name, table| create_from_table(model_name, table) endFriday, February 4, 2011
  111. 111. Generic Factory Step module FabricationMethods def create_from_table(model_name, table, extra = {}) fabricator_name = generate_fabricator_name(model_name) is_singular = model_name.to_s.singularize == model_name.to_s hashes = is_singular ? [table.rows_hash] : table.hashes @they = hashes.map do |hash| hash = hash.merge(extra).inject({}) {|h,(k,v)| h.update(k.gsub(/W+/,_).to_sym => v) Fabricate(fabricator_name, hash) end if is_singular @it = @they.last instance_variable_set("@#{fabricator_name}", @it) end end def generate_fabricator_name(model_name) model_name.gsub(/W+/, _).downcase.singularize.to_sym end end World(FabricationMethods) When /^the following ([^"]*):$/ do |model_name, table| create_from_table(model_name, table) endFriday, February 4, 2011
  112. 112. Generic Factory Step module FabricationMethods def create_from_table(model_name, table, extra = {}) fabricator_name = generate_fabricator_name(model_name) is_singular = model_name.to_s.singularize == model_name.to_s hashes = is_singular ? [table.rows_hash] : table.hashes @they = hashes.map do |hash| hash = hash.merge(extra).inject({}) {|h,(k,v)| h.update(k.gsub(/W+/,_).to_sym => v) Fabricate(fabricator_name, hash) end if is_singular @it = @they.last instance_variable_set("@#{fabricator_name}", @it) end end def generate_fabricator_name(model_name) model_name.gsub(/W+/, _).downcase.singularize.to_sym end end World(FabricationMethods) When /^the following ([^"]*):$/ do |model_name, table| create_from_table(model_name, table) endFriday, February 4, 2011
  113. 113. Easy Relationships Scenario: Has/Belongs to Relationships Given the following movie: | title | Gone with the wind | | year | 1939 | And that movie has the following role: | name | Scarlett OHara | And that role has the following actor: | name | Vivian Leigh | And that movie has the following role: | name | Rhett Butler | And that role has the following actor: | name | Clark Gable | When I go to the home page And I follow "Gone with the wind (1939)" Then I should see "Scarlett OHara - Vivian Leigh" And I should see "Rhett Butler - Clark Gable"Friday, February 4, 2011
  114. 114. Easy Relationships Scenario: Has/Belongs to Relationships Given the following movie: | title | Gone with the wind | | year | 1939 | And that movie has the following role: | name | Scarlett OHara | And that role has the following actor: | name | Vivian Leigh | And that movie has the following role: | name | Rhett Butler | And that role has the following actor: | name | Clark Gable | When I go to the home page And I follow "Gone with the wind (1939)" Then I should see "Scarlett OHara - Vivian Leigh" And I should see "Rhett Butler - Clark Gable"Friday, February 4, 2011
  115. 115. Easy Relationships Scenario: Has/Belongs to Relationships Given the following movie: | title | Gone with the wind | | year | 1939 | And that movie has the following role: | name | Scarlett OHara | And that role has the following actor: | name | Vivian Leigh | And that movie has the following role: | name | Rhett Butler | And that role has the following actor: | name | Clark Gable | When I go to the home page And I follow "Gone with the wind (1939)" Then I should see "Scarlett OHara - Vivian Leigh" And I should see "Rhett Butler - Clark Gable"Friday, February 4, 2011
  116. 116. Easy Relationships Scenario: Has/Belongs to Relationships Given the following movie: | title | Gone with the wind | | year | 1939 | And that movie has the following role: | name | Scarlett OHara | And that role has the following actor: | name | Vivian Leigh | And that movie has the following role: | name | Rhett Butler | And that role has the following actor: | name | Clark Gable | When I go to the home page And I follow "Gone with the wind (1939)" Then I should see "Scarlett OHara - Vivian Leigh" And I should see "Rhett Butler - Clark Gable"Friday, February 4, 2011
  117. 117. Confident! And Happy!Friday, February 4, 2011
  118. 118. TransformsFriday, February 4, 2011
  119. 119. Step Argument Transform Scenario: Step argument transforms Given the following movie: | title | Gone with the wind | | year | 1939 | When that movie has been liked 5 times And I go to the home page Then I should see "5 likes"Friday, February 4, 2011
  120. 120. Step Argument Transform Scenario: Step argument transforms Given the following movie: | title | Gone with the wind | | year | 1939 | When that movie has been liked 5 times And I go to the home page Then I should see "5 likes"Friday, February 4, 2011
  121. 121. Step Argument Transform When /^that movie has been liked (d+) times$/ do |count| count.to_i.times do |i| @movie.like! end endFriday, February 4, 2011
  122. 122. Step Argument Transform When /^that movie has been liked (d+) times$/ do |count| count.to_i.times do |i| @movie.like! end endFriday, February 4, 2011
  123. 123. Step Argument Transform # Convert a or an to the integer value 1 Transform /^(an?|-?d+)$/ do |amount| amount =~ /an?/ ? 1 : amount.to_i end When /^that movie has been liked (an?|-?d+) times$/ do |count| count.times do |i| @movie.like! end endFriday, February 4, 2011
  124. 124. Step Argument Transform # Convert a or an to the integer value 1 Transform /^(an?|-?d+)$/ do |amount| amount =~ /an?/ ? 1 : amount.to_i end When /^that movie has been liked (an?|-?d+) times$/ do |count| count.times do |i| @movie.like! end endFriday, February 4, 2011
  125. 125. Step Argument Transform # Convert a or an to the integer value 1 Transform /^(an?|-?d+)$/ do |amount| amount =~ /an?/ ? 1 : amount.to_i end When /^that movie has been liked (an?|-?d+) times$/ do |count| count.times do |i| @movie.like! end endFriday, February 4, 2011
  126. 126. Step Argument Transform # Convert a or an to the integer value 1 Transform /^(an?|-?d+)$/ do |amount| amount =~ /an?/ ? 1 : amount.to_i end When /^that movie has been liked (an?|-?d+) times$/ do |count| count.times do |i| @movie.like! end endFriday, February 4, 2011
  127. 127. Not so HappyFriday, February 4, 2011
  128. 128. Step Argument Transforms Scenario: Context is king Given the following movie: | title | Gone with the wind | | year | 1939 | When the movie "Gone with the wind" has been liked 5 times And I go to the home page Then I should see "5 likes"Friday, February 4, 2011
  129. 129. Step Argument Transforms Scenario: Context is king Given the following movie: | title | Gone with the wind | | year | 1939 | When the movie "Gone with the wind" has been liked 5 times And I go to the home page Then I should see "5 likes"Friday, February 4, 2011
  130. 130. Step Argument Transforms Transform /^movie "([^"]+)"$/ do |title| Movie.find_by_title(title) end When /^the (movie "(?:[^"]+)") has been liked (an?|-?d+) times$/ do |movie, count| count.times do |i| movie.like! end endFriday, February 4, 2011
  131. 131. Step Argument Transforms Transform /^movie "([^"]+)"$/ do |title| Movie.find_by_title(title) end When /^the (movie "(?:[^"]+)") has been liked (an?|-?d+) times$/ do |movie, count| count.times do |i| movie.like! end endFriday, February 4, 2011
  132. 132. Step Argument Transforms Transform /^movie "([^"]+)"$/ do |title| Movie.find_by_title(title) end When /^the (movie "(?:[^"]+)") has been liked (an?|-?d+) times$/ do |movie, count| count.times do |i| movie.like! end endFriday, February 4, 2011
  133. 133. Step Argument Transforms Transform /^movie "([^"]+)"$/ do |title| Movie.find_by_title(title) end When /^the (movie "(?:[^"]+)") has been liked (an?|-?d+) times$/ do |movie, count| count.times do |i| movie.like! end endFriday, February 4, 2011
  134. 134. Confident! And Happy!Friday, February 4, 2011
  135. 135. Table Transforms Transform /^table:name,actor$/ do |table| table.map_column!(:actor) do |actor_name| Actor.find_by_name(actor_name) end table endFriday, February 4, 2011
  136. 136. Table Transforms Transform /^table:name,actor$/ do |table| table.map_column!(:actor) do |actor_name| Actor.find_by_name(actor_name) end table endFriday, February 4, 2011
  137. 137. Table Transforms Transform /^table:name,actor$/ do |table| table.map_column!(:actor) do |actor_name| Actor.find_by_name(actor_name) end table endFriday, February 4, 2011
  138. 138. Table Transforms Transform /^table:name,actor$/ do |table| table.map_column!(:actor) do |actor_name| Actor.find_by_name(actor_name) end table endFriday, February 4, 2011
  139. 139. Table Transforms Scenario: Relationships using step transforms to transform the table Given the following movie: | title | Gone with the wind | | year | 1939 | And that movie has the following roles: | name | actor | | Scarlett OHara | Vivian Leigh | | Rhett Butler | Clark Gable | When I go to the home page And I follow "Gone with the wind (1939)" Then I should see "Scarlett OHara - Vivian Leigh" And I should see "Rhett Butler - Clark Gable"Friday, February 4, 2011
  140. 140. Table Transforms Scenario: Relationships using step transforms to transform the table Given the following movie: | title | Gone with the wind | | year | 1939 | And that movie has the following roles: | name | actor | | Scarlett OHara | Vivian Leigh | | Rhett Butler | Clark Gable | When I go to the home page And I follow "Gone with the wind (1939)" Then I should see "Scarlett OHara - Vivian Leigh" And I should see "Rhett Butler - Clark Gable"Friday, February 4, 2011
  141. 141. Table Transforms Transform /^table:name,actor$/ do |table| table.map_column!(:actor) do |actor_name| Fabricate(:actor, :name => actor_name) end table endFriday, February 4, 2011
  142. 142. HappyFriday, February 4, 2011
  143. 143. Not so HappyFriday, February 4, 2011
  144. 144. Better UI ScopesFriday, February 4, 2011
  145. 145. Shipped Web StepsScenario: Viewing a group When @philip_jay_fry signs in And I go to the “Planet Express” group Then I should see "Planet_Express" within "//h2" And I should see "t_leela" within "//ul/li[@id=t_leela]" And I should see "dr_hjfarnsworth" within "//ul/li[@id=dr_hjfarnsworFriday, February 4, 2011
  146. 146. Shipped Web StepsScenario: Viewing a group When @philip_jay_fry signs in And I go to the “Planet Express” group Then I should see "Planet_Express" within "//h2" And I should see "t_leela" within "//ul/li[@id=t_leela]" And I should see "dr_hjfarnsworth" within "//ul/li[@id=dr_hjfarnsworFriday, February 4, 2011
  147. 147. Shipped Web Steps module WithinHelpers 13def with_scope(locator) 14 locator ? within(locator) { yield } : yield 15end 16 end 17 World(WithinHelpers) 18 27 When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector| 28 with_scope(selector) do 29 click_button(button) 30 end 31 end 32 33 When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| 34 with_scope(selector) do 35 click_link(link) 36 end 37 end 38 39 When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field 40 with_scope(selector) do 41 fill_in(field, :with => value) 42 end 43 end 44Friday, February 4, 2011
  148. 148. Shipped Web Steps module WithinHelpers 13def with_scope(locator) 14 locator ? within(locator) { yield } : yield 15end 16 end 17 World(WithinHelpers) 18 27 When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector| 28 with_scope(selector) do 29 click_button(button) 30 end 31 end 32 33 When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| 34 with_scope(selector) do 35 click_link(link) 36 end 37 end 38 39 When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field 40 with_scope(selector) do 41 fill_in(field, :with => value) 42 end 43 end 44Friday, February 4, 2011
  149. 149. Shipped Web Steps module WithinHelpers 13def with_scope(locator) 14 locator ? within(locator) { yield } : yield 15end 16 end 17 World(WithinHelpers) 18 27 When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector| 28 with_scope(selector) do 29 click_button(button) 30 end 31 end 32 33 When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| 34 with_scope(selector) do 35 click_link(link) 36 end 37 end 38 39 When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field 40 with_scope(selector) do 41 fill_in(field, :with => value) 42 end 43 end 44Friday, February 4, 2011
  150. 150. Shipped Web Steps module WithinHelpers 13def with_scope(locator) 14 locator ? within(locator) { yield } : yield 15end 16 end 17 World(WithinHelpers) 18 27 When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector| 28 with_scope(selector) do 29 click_button(button) 30 end 31 end 32 33 When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| 34 with_scope(selector) do 35 click_link(link) 36 end 37 end 38 39 When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field 40 with_scope(selector) do 41 fill_in(field, :with => value) 42 end 43 end 44Friday, February 4, 2011
  151. 151. Shipped Web Steps module WithinHelpers 13def with_scope(locator) 14 locator ? within(locator) { yield } : yield 15end 16 end 17 World(WithinHelpers) 18 27 When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector| 28 with_scope(selector) do 29 click_button(button) 30 end 31 end 32 33 When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| 34 with_scope(selector) do 35 click_link(link) 36 end 37 end 38 39 When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field 40 with_scope(selector) do 41 fill_in(field, :with => value) 42 end 43 end 44Friday, February 4, 2011
  152. 152. Not so HappyFriday, February 4, 2011
  153. 153. Removing CSS/XPath Scenario: Simple and Direct Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" in the movie listFriday, February 4, 2011
  154. 154. Removing CSS/XPath Scenario: Simple and Direct Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" in the movie listFriday, February 4, 2011
  155. 155. Removing CSS/XPath Scenario: Simple and Direct Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" in the movie list { "in the movie list" => .movies }.each do |within, selector| When /^(.+) #{within}$/ do |step| with_scope(selector) do When step end end endFriday, February 4, 2011
  156. 156. Removing CSS/XPath Scenario: Simple and Direct Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" in the movie list { "in the movie list" => .movies }.each do |within, selector| When /^(.+) #{within}$/ do |step| with_scope(selector) do When step end end endFriday, February 4, 2011
  157. 157. Removing CSS/XPath Scenario: Simple and Direct Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" in the movie list { "in the movie list" => .movies }.each do |within, selector| When /^(.+) #{within}$/ do |step| with_scope(selector) do When step end end endFriday, February 4, 2011
  158. 158. Removing CSS/XPath Scenario: Simple and Direct Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" in the movie list { "in the movie list" => .movies }.each do |within, selector| When /^(.+) #{within}$/ do |step| with_scope(selector) do When step end end endFriday, February 4, 2011
  159. 159. Removing CSS/XPath Scenario: Simple and Direct Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" in the movie list { "in the movie list" => .movies }.each do |within, selector| When /^(.+) #{within}$/ do |step| with_scope(selector) do When step end end endFriday, February 4, 2011
  160. 160. HappyFriday, February 4, 2011
  161. 161. Removing CSS/XPath Scenario: Using selector_for Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" within the movie listFriday, February 4, 2011
  162. 162. Removing CSS/XPath Scenario: Using selector_for Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" within the movie listFriday, February 4, 2011
  163. 163. Removing CSS/XPath Scenario: Using selector_for Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" within the movie list When /^(.*) within ([^:"]+)$/ do |step, scope| with_scope(selector_for(scope)) do When step end endFriday, February 4, 2011
  164. 164. Removing CSS/XPath Scenario: Using selector_for Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" within the movie list When /^(.*) within ([^:"]+)$/ do |step, scope| with_scope(selector_for(scope)) do When step end endFriday, February 4, 2011
  165. 165. Removing CSS/XPath Scenario: Using selector_for Given the following movie: | title | Gone with the wind | | year | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" within the movie list When /^(.*) within ([^:"]+)$/ do |step, scope| with_scope(selector_for(scope)) do When step end endFriday, February 4, 2011
  166. 166. selector_for module HtmlSelectorsHelper def selector_for(scope) case scope when /the body/ "html > body" when /the movie list/ ".movies" else raise "Cant find mapping from "#{scope}" to a selector.n" + "Now, go and add a mapping in #{__FILE__}" end end end World(HtmlSelectorsHelper)Friday, February 4, 2011
  167. 167. HappyFriday, February 4, 2011
  168. 168. Persistent ScopesScenario: Persistent scoping Given the following movies: | title | year | | Gone with the wind | 1939 | | The Wizard of Oz | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" within the movie list And also I should see "The Wizard of Oz (1939)"Friday, February 4, 2011
  169. 169. Persistent ScopesScenario: Persistent scoping Given the following movies: | title | year | | Gone with the wind | 1939 | | The Wizard of Oz | 1939 | When I go to the home page Then I should see "Gone with the wind (1939)" within the movie list And also I should see "The Wizard of Oz (1939)"Friday, February 4, 2011
  170. 170. Persistent Scopes module PersistentScope def persistent_scope(scope = nil) if scope page.find(scope) @persistent_scope = scope end @persistent_scope end end World(PersistentScope) When /^(.*) within ([^:"]+)$/ do |step, scope| with_scope(persistent_scope(selector_for(scope))) do When step end end When /^also (.*)$/ do |step| fail unless persistent_scope with_scope(persistent_scope) do When step end endFriday, February 4, 2011
  171. 171. Persistent Scopes module PersistentScope def persistent_scope(scope = nil) if scope page.find(scope) @persistent_scope = scope end @persistent_scope end end World(PersistentScope) When /^(.*) within ([^:"]+)$/ do |step, scope| with_scope(persistent_scope(selector_for(scope))) do When step end end When /^also (.*)$/ do |step| fail unless persistent_scope with_scope(persistent_scope) do When step end endFriday, February 4, 2011
  172. 172. Persistent Scopes module PersistentScope def persistent_scope(scope = nil) if scope page.find(scope) @persistent_scope = scope end @persistent_scope end end World(PersistentScope) When /^(.*) within ([^:"]+)$/ do |step, scope| with_scope(persistent_scope(selector_for(scope))) do When step end end When /^also (.*)$/ do |step| fail unless persistent_scope with_scope(persistent_scope) do When step end endFriday, February 4, 2011
  173. 173. Persistent Scopes module PersistentScope def persistent_scope(scope = nil) if scope page.find(scope) @persistent_scope = scope end @persistent_scope end end World(PersistentScope) When /^(.*) within ([^:"]+)$/ do |step, scope| with_scope(persistent_scope(selector_for(scope))) do When step end end When /^also (.*)$/ do |step| fail unless persistent_scope with_scope(persistent_scope) do When step end endFriday, February 4, 2011
  174. 174. Persistent Scopes module PersistentScope def persistent_scope(scope = nil) if scope page.find(scope) @persistent_scope = scope end @persistent_scope end end World(PersistentScope) When /^(.*) within ([^:"]+)$/ do |step, scope| with_scope(persistent_scope(selector_for(scope))) do When step end end When /^also (.*)$/ do |step| fail unless persistent_scope with_scope(persistent_scope) do When step end endFriday, February 4, 2011
  175. 175. Confident! And Happy!Friday, February 4, 2011
  176. 176. Write Better ScenariosFriday, February 4, 2011
  177. 177. ImperativeScenario: Successful animal creation Given Im on the animal creation page When I fill in Name with Alligator And select Phylum as Chordata And fill in Animal Class with Sauropsida And fill in Order with Crocodilia And fill in Family with Alligatoridae And fill in Genus with Alligator And check Lay Eggs And click the Create button Then I should see the notice Thank you for your animal submission! And the page should include the animals name, phylum, animal class,Friday, February 4, 2011
  178. 178. Declarative Scenario: Successful animal creation Given Im on the animal creation page When I add a new animal Then I should see the page for my newly created animal And the notice Thank you for your animal submission!Friday, February 4, 2011
  179. 179. UX Feature: Visitor uses advertiser carousel Background: Given the following advertiser: | name | Lowes | And that advertiser has the following coupons: | description | | Free free free | And the following advertiser: | name | Home Depot | And that advertiser has the following coupons: | description | | Buy three storage bins and get the next 20 absolutely free for a limited time! | When I go to the homepage Scenario: populating the carousel Then I should see "Lowes coupons" within the advertiser carousel And I should see "Free free free" within the advertiser carousel And I should see "Home Depot coupons" within the advertiser carousel And I should see "Buy three storage" within the advertiser carousel Scenario: truncating the coupon copy Then I should see "Buy three storage bins and get the next 20 absolute..." within the advertiser carousel Scenario: viewing all coupons for an advertiser When I follow "Lowes coupons" within the advertiser carousel Then I should see "Coupons for Lowes" And I should see "Free free free" And I should not see "Buy three storage bins" And I should not see "View all Lowes coupons"Friday, February 4, 2011
  180. 180. Outside InFriday, February 4, 2011
  181. 181. Confident! And Happy!Friday, February 4, 2011
  182. 182. Cucumber: The Bad PartsFriday, February 4, 2011
  183. 183. Not so HappyFriday, February 4, 2011
  184. 184. Cucumber: The Good PartFriday, February 4, 2011
  185. 185. HappyFriday, February 4, 2011
  186. 186. Thank you!Friday, February 4, 2011

×