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

Cucumber Ain't Bad, You Are Just Doing It Wrong

Cucumber Ain't Bad, You Are Just Doing It Wrong

The cry from developers is unanimous: “I don’t like Cucumber. My acceptance tests are brittle and hard to maintain!” And in fact, they can be.

This presentation will show you what tools and techniques you should use to write independent, stateless step definitions that can be weaved together to form a testing DSL.

Avatar for Attila Domokos

Attila Domokos

December 04, 2014
Tweet

Other Decks in Programming

Transcript

  1. FIT (Framework for Integrated Tests) Basic Employee Compensation For each

    week, hourly employees are paid a standard wage per hour for the first 40 hours worked, 1.5 times their wage for each hour after the first 40 hours, and 2 times their wage for each hour worked on Sundays and holidays. Here are some examples of this: Payroll.Fixtures.WeeklyCompensation StandardHours HolidayHours Wage Pay() 40 0 20 $800 45 0 20 $950 48 8 20 $1360 expected —————— $1040 actual
  2. RSPEC Documentation $: bin/rspec spec/features/proposal_spec.rb -fd Proposals when submitting with

    an existing bio shows the user's bio in the bio field with pitch and details submits successfully does not create an empty comment shows the proposal on the user's proposals list when editing user edits their proposal when commenting user comments on their proposal does not show the speaker's name when confirming when the proposal has not yet been confirmed marks the proposal as confirmed redirects the user to the proposal page …
  3. GHERKIN Syntax Feature: A user can log on Scenario: User

    can log on to the site Given I am a user with login access When I log in Then I should be logged in
  4. YOU MIGHT BE DOING IT WRONG CUCUMBER AIN’T BAD. GHERKIN

    BEST PRACTICES CUCUMBER STEP DEFINITION RECIPES
  5. FIRST Scenario Feature: A user can set the profile information

    Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page When I fill in “female” for “Gender identity” And I fill in “asian” for “Ethnicity” And I select “USA” under “Country” And I click on the Save button Then my demographics info is updated
  6. FIRST Scenario Feature: A user can set the profile information

    Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page When I fill in “female” for “Gender identity” And I fill in “asian” for “Ethnicity” And I select “USA” under “Country” And I click on the Save button Then my demographics info is updated
  7. FIRST Scenario Feature: A user can set the profile information

    Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page When I fill in “female” for “Gender identity” And I fill in “asian” for “Ethnicity” And I select “USA” under “Country” And I click on the Save button Then my demographics info is updated
  8. FIRST Scenario Feature: A user can set the profile information

    Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page And I fill in “female” for “Gender identity” And I fill in “asian” for “Ethnicity” And I select “USA” under “Country” When I click on the Save button Then my demographics info is updated
  9. DON’T Test the UI Feature: A user can set the

    profile information Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page And I fill in “female” for “Gender identity” And I fill in “asian” for “Ethnicity” And I select “USA” under “Country” When I click on the Save button Then my demographics info is updated
  10. DON’T Test the UI Feature: A user can set the

    profile information Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page And I set up my demographics info When I click on the Save button Then my demographics info is updated
  11. DON’T Test the UI Feature: A user can set the

    profile information Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page And I set up my demographics info When I click on the Save button Then my demographics info is updated
  12. DON’T Test the UI Feature: A user can set the

    profile information Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page And I set up my demographics info When I submit the profile form Then my demographics info is updated
  13. STRUCTURE of a Scenario Feature: A user can set the

    profile information Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page And I set up my demographics info When I submit the profile form Then my demographics info is updated
  14. STRUCTURE of a Scenario Feature: A user can set the

    profile information Scenario: User can set up the demographics info Given I am logged on as a user # Set up test persona And I don’t have demographics info And I am on the edit profile page And I set up my demographics info When I submit the profile form Then my demographics info is updated
  15. STRUCTURE of a Scenario Feature: A user can set the

    profile information Scenario: User can set up the demographics info Given I am logged on as a user # Set up test persona And I don’t have demographics info # Set the context And I am on the edit profile page And I set up my demographics info When I submit the profile form Then my demographics info is updated
  16. STRUCTURE of a Scenario Feature: A user can set the

    profile information Scenario: User can set up the demographics info Given I am logged on as a user # Set up test persona And I don’t have demographics info # Set the context And I am on the edit profile page # Visit the page And I set up my demographics info When I submit the profile form Then my demographics info is updated
  17. STRUCTURE of a Scenario Feature: A user can set the

    profile information Scenario: User can set up the demographics info Given I am logged on as a user # Set up test persona And I don’t have demographics info # Set the context And I am on the edit profile page # Visit the page And I set up my demographics info # Perform action When I submit the profile form Then my demographics info is updated
  18. STRUCTURE of a Scenario Feature: A user can set the

    profile information Scenario: User can set up the demographics info Given I am logged on as a user # Set up test persona And I don’t have demographics info # Set the context And I am on the edit profile page # Visit the page And I set up my demographics info # Perform action When I submit the profile form # Trigger state change Then my demographics info is updated
  19. STRUCTURE of a Scenario Feature: A user can set the

    profile information Scenario: User can set up the demographics info Given I am logged on as a user # Set up test persona And I don’t have demographics info # Set the context And I am on the edit profile page # Visit the page And I set up my demographics info # Perform action When I submit the profile form # Trigger state change Then my demographics info is updated # Verify post-state
  20. SIX TYPES of Steps. Set up the test persona Set

    up the the context Visit the page Perform the action Trigger state transition Verify post-state 1 2 3 4 5 6
  21. SIX TYPES of Steps. Set up the test persona Set

    up the the context Visit the page Perform the action Trigger state transition Verify post-state 1 2 3 4 5 6 Given I am logged on as an admin And my organization has 3 users And I am on the users page When I delete a user Then my organization has 2 users
  22. SECOND Scenario Feature: A user can set the profile information

    Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page And I set up my demographics info When I submit the profile form Then my demographics info is updated Scenario: User can set up the bio Given I am logged on as a user And I don’t have a bio And I am on the edit profile page And I set up my bio When I submit the profile form Then my bio is updated
  23. USE TEXT for Clarity Feature: A user can set the

    profile information A user can set up both the demographics info and bio using the same form. Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page And I set up my demographics info When I submit the profile form Then my demographics info is updated Scenario: User can set up the bio Given I am logged on as a user And I don’t have a bio And I am on the edit profile page And I set up my bio When I submit the profile form Then my bio is updated
  24. COMMON Background Feature: A user can set the profile information

    Scenario: User can set up the demographics info Given I am logged on as a user And I don’t have demographics info And I am on the edit profile page And I set up my demographics info When I submit the profile form Then my demographics info is updated Scenario: User can set up the bio Given I am logged on as a user And I don’t have a bio And I am on the edit profile page And I set up my bio When I submit the profile form Then my bio is updated
  25. COMMON Background Feature: A user can set the profile information

    Scenario: User can set up the demographics info Given I am logged on as a user And my profile info is not set up And I am on the edit profile page And I set up my demographics info When I submit the profile form Then my demographics info is updated Scenario: User can set up the bio Given I am logged on as a user And my profile info is not set up And I am on the edit profile page And I set up my bio When I submit the profile form Then my bio is updated
  26. COMMON Background Feature: A user can set the profile information

    Scenario: User can set up the demographics info Given I am logged on as a user And my profile info is not set up And I am on the edit profile page And I set up my demographics info When I submit the profile form Then my demographics info is updated Scenario: User can set up the bio Given I am logged on as a user And my profile info is not set up And I am on the edit profile page And I set up my bio When I submit the profile form Then my bio is updated
  27. COMMON Background Feature: A user can set the profile information

    Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Scenario: User can set up the demographics info Given I set up my demographics info When I submit the profile form Then my demographics info is updated Scenario: User can set up the bio Given I set up my bio When I submit the profile form Then my bio is updated
  28. DRY-ing up Scenarios Feature: A user can set the profile

    information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Scenario: User can set up the demographics info Given I set up my demographics info When I submit the profile form Then my demographics info is updated Scenario: User can set up the bio Given I set up my bio When I submit the profile form Then my bio is updated
  29. SCENARIO Outline Feature: A user can set the profile information

    Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Scenario Outline: User can set up the profile information Given I set up my <subject> When I submit the profile form Then my <subject> is updated Examples: | subject | | demographics info | | bio |
  30. YOU MIGHT BE DOING IT WRONG CUCUMBER AIN’T BAD. GHERKIN

    BEST PRACTICES CUCUMBER STEP DEFINITION RECIPES
  31. EXECUTING the Feature $: bin/cucumber features/profile.feature Using the default profile...

    Feature: A user can set the profile information Background: Given I am logged on as a user Undefined step: "I am logged on as a user” features/profile.feature:4:in `Given I am logged on as a user' And my profile info is not set up Undefined step: "I my profile info is not set up” features/profile.feature:5:in `And I my profile info is not set up' And I am on the edit profile page Undefined step: "I am on the edit profile page" features/profile.feature:6:in `And I am on the edit profile page'
  32. EXECUTING the Feature You can implement step definitions for undefined

    steps with these snippets: Given(/^I am logged on as a user$/) do pending # express the regexp above with the code you wish you had end Given(/^I my profile info is not set up$/) do pending # express the regexp above with the code you wish you had end Given(/^I am on the edit profile page$/) do pending # express the regexp above with the code you wish you had end
  33. SET UP the Test Persona Given(/^I am logged on as

    a user$/) do @user = FactoryGirl.create(:person) login_user(@user) end def login_user(user) allow(Person).to receive(:authenticate) .and_return(‘developer’, user) allow(Person).to receive(:find_by_id).and_return(user) Person.authenticate(user) end $: cat features/step_definitions/profile_steps.rb
  34. USE Factories Given(/^I am logged on as a user$/) do

    @user = FactoryGirl.create(:person) login_user(@user) end def login_user(user) allow(Person).to receive(:authenticate) .and_return(‘developer’, user) allow(Person).to receive(:find_by_id).and_return(user) Person.authenticate(user) end $: cat features/step_definitions/profile_steps.rb
  35. EXECUTING the Feature $: bin/cucumber features/profile.feature Using the default profile...

    Feature: A user can set the profile information Background: Given I am logged on as a user And my profile info is not set up Undefined step: "I my profile info is not set up” features/profile.feature:5:in `And I my profile info is not set up' And I am on the edit profile page Undefined step: "I am on the edit profile page" features/profile.feature:6:in `And I am on the edit profile page'
  36. SET UP the Context Given(/^I am logged on as a

    user$/) do @user = FactoryGirl.create(:person) login_user(@user) end Given(/^my profile info is not set up$/) do @user.demographics[‘gender’] = nil @user.demographics[‘ethnicity’] = nil @user.demographics[‘country’] = nil @user.save! end $: cat features/step_definitions/profile_steps.rb
  37. FAIL Fast Given(/^I am logged on as a user$/) do

    @user = FactoryGirl.create(:person) login_user(@user) end Given(/^my profile info is not set up$/) do @user.demographics[‘gender’] = nil @user.demographics[‘ethnicity’] = nil @user.demographics[‘country’] = nil @user.save! end $: cat features/step_definitions/profile_steps.rb
  38. EXECUTING the Feature $: bin/cucumber features/profile.feature Using the default profile...

    Feature: A user can set the profile information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Undefined step: "I am on the edit profile page" features/profile.feature:6:in `And I am on the edit profile page'
  39. COUPLING Between Steps Given(/^I am logged on as a user$/)

    do @user = FactoryGirl.create(:person) login_user(@user) end Given(/^my profile info is not set up$/) do @user.demographics[‘gender’] = nil @user.demographics[‘ethnicity’] = nil @user.demographics[‘country’] = nil @user.save! end $: cat features/step_definitions/profile_steps.rb
  40. COUPLING Between Steps Given(/^I am logged on as a user$/)

    do @user = FactoryGirl.create(:person) login_user(@user) end Given(/^my profile info is not set up$/) do user = Person.last user.demographics[‘gender’] = nil user.demographics[‘ethnicity’] = nil user.demographics[‘country’] = nil user.save! end $: cat features/step_definitions/profile_steps.rb
  41. STATELESS Step Definitions Given(/^I am logged on as a user$/)

    do user = FactoryGirl.create(:person) login_user(user) end Given(/^my profile info is not set up$/) do user = Person.last user.demographics[‘gender’] = nil user.demographics[‘ethnicity’] = nil user.demographics[‘country’] = nil user.save! end $: cat features/step_definitions/profile_steps.rb
  42. EXECUTING the Feature $: bin/cucumber features/profile.feature Using the default profile...

    Feature: A user can set the profile information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Undefined step: "I am on the edit profile page" features/profile.feature:6:in `And I am on the edit profile page'
  43. CLEAN UP the DB Given(/^I am logged on as a

    user$/) do user = FactoryGirl.create(:person) login_user(user) end Given(/^my profile info is not set up$/) do p “Number of users: %s” % Person.count user = Person.last user.demographics[‘gender’] = nil user.demographics[‘ethnicity’] = nil user.demographics[‘country’] = nil user.save! end $: cat features/step_definitions/profile_steps.rb
  44. EXECUTING the Feature $: bin/cucumber features/profile.feature Using the default profile...

    Feature: A user can set the profile information Background: Given I am logged on as a user And my profile info is not set up Number of users: 1 And I am on the edit profile page Undefined step: "I am on the edit profile page" features/profile.feature:6:in `And I am on the edit profile page'
  45. EXECUTING the Feature - Again $: bin/cucumber features/profile.feature Using the

    default profile... Feature: A user can set the profile information Background: Given I am logged on as a user And my profile info is not set up Number of users: 1 And I am on the edit profile page Undefined step: "I am on the edit profile page" features/profile.feature:6:in `And I am on the edit profile page'
  46. USE Database Cleaner begin DatabaseCleaner.strategy = :transaction rescue NameError raise

    "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it." end $: cat features/support/env.rb
  47. FAST LOADING Seed Data Before do Helper::AddsSeedData.execute end module Helper

    class AddsSeedData def self.execute config = Rails.configuration.database_configuration database = config[Rails.env].fetch(“database”) username = config[Rails.env].fetch(“username”) insert_script = “psql -q -d #{database} --username #{username} -f db/data/add_superadmin.dump > /dev/ null -h localhost” system(insert_script) end end end
  48. DOING Work for the Model Given(/^I am logged on as

    a user$/) do user = FactoryGirl.create(:person) login_user(user) end Given(/^my profile info is not set up$/) do user = Person.last user.demographics[‘gender’] = nil user.demographics[‘ethnicity’] = nil user.demographics[‘country’] = nil user.save! end $: cat features/step_definitions/profile_steps.rb
  49. MOVE Logic to the Model class Person < ActiveRecord::Base ...

    def clear_demographics_info self.demographics[‘gender’] = nil self.demographics[‘ethnicity’] = nil self.demographics[‘country’] = nil end end $: cat app/models/person.rb
  50. DELEGATE Logic to Models Given(/^I am logged on as a

    user$/) do user = FactoryGirl.create(:person) login_user(user) end Given(/^my profile info is not set up$/) do user = Person.last user.clear_demographics_info user.save! end $: cat features/step_definitions/profile_steps.rb
  51. VISIT the Page Given(/^I am logged on as a user$/)

    do user = FactoryGirl.create(:person) login_user(user) end Given(/^my profile info is not set up$/) do user = Person.last user.clear_demographics_info user.save! end Given(/^I am on the edit profile page$/) do page.visit edit_profile_path end $: cat features/step_definitions/profile_steps.rb
  52. EXECUTING the Feature $: bin/cucumber features/profile.feature Feature: A user can

    set the profile information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Scenario Outline: A user can add profile information Given I set up my <subject> When I submit the profile form Then my <subject> is updated Examples: | subject | | demographics info | Undefined step: "I set up my demographics info" | bio | Undefined step: "I set up my bio"
  53. PERFORM Action ... Given(/^I am on the edit profile page$/)

    do page.visit edit_profile_path end Given(/^I set up my demographics info$/) do page.fill_in ‘person[gender]’, with: ‘female’ page.fill_in ‘person[ethnicity]’, with: ‘Asian’ page.select(‘United States of America’, from: ’person[country]’) end $: cat features/step_definitions/profile_steps.rb
  54. EXECUTING the Feature $: bin/cucumber features/profile.feature Feature: A user can

    set the profile information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Scenario Outline: A user can add profile information Given I set up my <subject> When I submit the profile form Then my <subject> is updated Examples: | subject | | demographics info | Undefined step: "I submit the profile form" | bio | Undefined step: "I set up my bio"
  55. TRIGGER State Change ... Given(/^I am on the edit profile

    page$/) do page.visit edit_profile_path end Given(/^I set up my demographics info$/) do page.fill_in ‘person[gender]’, with: ‘female’ page.fill_in ‘person[ethnicity]’, with: ‘Asian’ page.select(‘United States of America’, from: ’person[country]’) end When(/^I submit the profile form$/) do page.click_button 'Save' end $: cat features/step_definitions/profile_steps.rb
  56. EXECUTING the Feature $: bin/cucumber features/profile.feature Feature: A user can

    set the profile information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Scenario Outline: A user can add profile information Given I set up my <subject> When I submit the profile form Then my <subject> is updated Examples: | subject | | demographics info | Undefined step: "my demographics info is updated" | bio | Undefined step: "I set up my bio"
  57. USE ID Not Label ... Given(/^I am on the edit

    profile page$/) do page.visit edit_profile_path end Given(/^I set up my demographics info$/) do page.fill_in ‘person[gender]’, with: ‘female’ page.fill_in ‘person[ethnicity]’, with: ‘Asian’ page.select(‘United States of America’, from: ’person[country]’) end When(/^I submit the profile form$/) do page.click_button 'Save' end $: cat features/step_definitions/profile_steps.rb
  58. USE IDs Not Labels ... Given(/^I am on the edit

    profile page$/) do page.visit edit_profile_path end Given(/^I set up my demographics info$/) do page.fill_in ‘person[gender]’, with: ‘female’ page.fill_in ‘person[ethnicity]’, with: ‘Asian’ page.select(‘United States of America’, from: ’person[country]’) end When(/^I submit the profile form$/) do page.click_button ‘submit_profile’ end $: cat features/step_definitions/profile_steps.rb
  59. EXECUTING the Feature $: bin/cucumber features/profile.feature Feature: A user can

    set the profile information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Scenario Outline: A user can add profile information Given I set up my <subject> When I submit the profile form Then my <subject> is updated Examples: | subject | | demographics info | Undefined step: "my demographics info is updated" | bio | Undefined step: "I set up my bio"
  60. VERIFY Post-State ... Given(/^I set up my demographics info$/) do

    page.fill_in ‘person[gender]’, with: ‘female’ page.fill_in ‘person[ethnicity]’, with: ‘Asian’ page.select(‘United States of America’, from: ’person[country]’) end When(/^I submit the profile form$/) do page.click_button ‘submit_profile‘ end Then(/^my demographics info is updated$/) do user = Person.last expect(user.demographics[‘gender’]).to eq(‘female’) expect(user.demographics[‘ethnicity’]).to eq(‘Asian’) expect(user.demographics[‘country’]).to eq(‘United States of America’) end $: cat features/step_definitions/profile_steps.rb
  61. EXECUTING the Feature $: bin/cucumber features/profile.feature Feature: A user can

    set the profile information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Scenario Outline: A user can add profile information Given I set up my <subject> When I submit the profile form Then my <subject> is updated Examples: | subject | | demographics info | | bio | Undefined step: "I set up my bio"
  62. DUPLICATED Logic ... Given(/^I set up my demographics info$/) do

    page.fill_in ‘person[gender]’, with: ‘female’ page.fill_in ‘person[ethnicity]’, with: ‘Asian’ page.select(‘United States of America’, from: ’person[country]’) end When(/^I submit the profile form$/) do page.click_button ‘submit_profile‘ end Then(/^my demographics info is updated$/) do user = Person.last expect(user.demographics[‘gender’]).to eq(‘female’) expect(user.demographics[‘ethnicity’]).to eq(‘Asian’) expect(user.demographics[‘country’]).to eq(‘United States of America’) end $: cat features/step_definitions/profile_steps.rb
  63. DUPLICATED Logic ... Given(/^I set up my demographics info$/) do

    page.fill_in ‘person[gender]’, with: ProfilePageHelper.demographics_info.fetch(:gender) page.fill_in ‘person[ethnicity]’, with: ProfilePageHelper.demographics_info.fetch(:ethnicity) page.select(ProfilePageHelper.demographics_info.fetch(:country), from: ’person[country]’) end module ProfilePageHelper def self.demographics_info { gender: ‘female’, ethnicity: ‘Asian’, country: ‘United States of America’ } end end $: cat features/step_definitions/profile_steps.rb
  64. DUPLICATED Logic ... Given(/^I set up my demographics info$/) do

    page.fill_in ‘person[gender]’, with: ProfilePageHelper.demographics_info.fetch(:gender) page.fill_in ‘person[ethnicity]’, with: ProfilePageHelper.demographics_info.fetch(:ethnicity) page.select(ProfilePageHelper.demographics_info.fetch(:country), from: ’person[country]’) end module ProfilePageHelper def self.demographics_info { gender: ‘female’, ethnicity: ‘Asian’, country: ‘United States of America’ } end end $: cat features/step_definitions/profile_steps.rb
  65. class ProfilePage attr_reader :page def initialize(page) @page = page end

    def set_up_demographics_info(args={}) demographics_info = self.default_demographics_info.merge(args) page.fill_in ‘person[gender]’, with: demographics_info.fetch(:gender) page.fill_in ‘person[ethnicity]’, with: demographics_info.fetch(:ethnicity) page.select(demographics_info.fetch(:country), from: ‘person[country]’) end def self.default_demographics_info { gender: ‘female’, ethnicity: ‘Asian’, country: ‘United States of America’ } end end $: cat features/step_definitions/profile_steps.rb
  66. SET the Demographics Info ... Given(/^I set up my demographics

    info$/) do ProfilePage.new(page).set_up_demographics_info end Then(/^my demographics info is updated$/) do demographics_info = ProfilePage.default_demographics_info user = Person.last expect(user.demographics[‘gender’]).to \ eq(demographics_info.fetch(:gender)) expect(user.demographics[‘ethnicity’]).to \ eq(demographics_info.fetch(:ethnicity)) expect(user.demographics[‘country’]).to \ eq(demographics_info.fetch(:country)) end $: cat features/step_definitions/profile_steps.rb
  67. GET the Default Data ... Given(/^I set up my demographics

    info$/) do ProfilePage.new(page).set_up_demographics_info end Then(/^my demographics info is updated$/) do demographics_info = ProfilePage.default_demographics_info user = Person.last expect(user.demographics[‘gender’]).to \ eq(demographics_info.fetch(:gender)) expect(user.demographics[‘ethnicity’]).to \ eq(demographics_info.fetch(:ethnicity)) expect(user.demographics[‘country’]).to \ eq(demographics_info.fetch(:country)) end $: cat features/step_definitions/profile_steps.rb
  68. EXECUTING the Feature $: bin/cucumber features/profile.feature Feature: A user can

    set the profile information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Scenario Outline: A user can add profile information Given I set up my <subject> When I submit the profile form Then my <subject> is updated Examples: | subject | | demographics info | | bio | Undefined step: "I set up my bio"
  69. HANDLING Bio class ProfilePage attr_reader :page ... def set_up_bio(bio=self.class.default_bio) page.fill_in(‘Bio’,

    with: bio) end def self.default_bio “My default bio.” end end $: cat features/step_definitions/profile_steps.rb
  70. ADDING Remaining Steps Given(/^my profile info is not set up$/)

    do user = Person.last user.clear_demographics_info user.bio = nil user.save! end Given(/^I set up my bio$/) do ProfilePage.new(page).set_up_bio end Given(/^my bio is updated$/) do user = Person.last expect(user.bio).to eq(ProfilePage.default_bio) end $: cat features/step_definitions/profile_steps.rb
  71. EXECUTING the Feature $: bin/cucumber features/profile.feature Feature: A user can

    set the profile information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Scenario Outline: A user can add profile information Given I set up my <subject> When I submit the profile form Then my <subject> is updated Examples: | subject | | demographics info | | bio |
  72. CLEARING Bio with the Model Given(/^my profile info is not

    set up$/) do user = Person.last user.clear_demographics_info user.bio = nil user.save! end Given(/^I set up my bio$/) do ProfilePage.new(page).set_up_bio end Given(/^my bio is updated$/) do user = Person.last expect(user.bio).to eq(ProfilePage.default_bio) end $: cat features/step_definitions/profile_steps.rb
  73. MOVE Logic to the Model class Person < ActiveRecord::Base ...

    def clear_demographics_info self.demographics[‘gender’] = nil self.demographics[‘ethnicity’] = nil self.demographics[‘country’] = nil self.bio = nil end end $: cat app/models/person.rb
  74. RENAME Method class Person < ActiveRecord::Base ... def clear_demographics_info self.demographics[‘gender’]

    = nil self.demographics[‘ethnicity’] = nil self.demographics[‘country’] = nil self.bio = nil end end $: cat app/models/person.rb
  75. RENAME Method class Person < ActiveRecord::Base ... def clear_profile_info self.demographics[‘gender’]

    = nil self.demographics[‘ethnicity’] = nil self.demographics[‘country’] = nil self.bio = nil end end $: cat app/models/person.rb
  76. CLEARING Bio with the Model Given(/^my profile info is not

    set up$/) do user = Person.last user.clear_profile_info user.save! end Given(/^I set up my bio$/) do ProfilePage.new(page).set_up_bio end Given(/^my bio is updated$/) do user = Person.last expect(user.bio).to eq(ProfilePage.default_bio) end $: cat features/step_definitions/profile_steps.rb
  77. EXECUTING the Feature $: bin/cucumber features/profile.feature Feature: A user can

    set the profile information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page Scenario Outline: A user can add profile information Given I set up my <subject> When I submit the profile form Then my <subject> is updated Examples: | subject | | demographics info | | bio |
  78. SOMETHING Goes Wrong $: bin/cucumber features/profile.feature Background: Given I am

    logged on as a user And my profile info is not set up And I am on the edit profile page Scenario Outline: A user can add profile information Given I set up my <subject> When I submit the profile form Then my <subject> is updated Examples: | subject | | demographics info | key not found: :gender (KeyError) ./features/step_definitions/profile_steps.rb:34:in `fetch' ./features/step_definitions/profile_steps.rb:34:in `/^my demographics info is updated$/' features/profile.feature:11:in `Then my <subject> is updated' | bio |
  79. PAUSE to Look Around Feature: A user can set the

    profile information Background: Given I am logged on as a user And my profile info is not set up And I am on the edit profile page @pause Scenario Outline: User can set up the profile information Given I set up my <subject> When I submit the profile form Then my <subject> is updated Examples: | subject | | demographics info | | bio | $: cat features/profile.feature
  80. PAUSE to Look Around $: bin/cucumber features/profile.feature Background: Press Return

    to continue... Given I am logged on as a user Press Return to continue... And my profile info is not set up Press Return to continue... And I am on the edit profile page ...
  81. CLEAN UP Unused Steps $: bin/cucumber -d -f usage Using

    the default profile... ------------------- /^I am a user$/ # login_steps.rb:1 Given I am a user # login.feature:4 /^I am logged on as a user$/ # profile_steps.rb:1 Given I am logged on as a user # events.feature:4 Given I am logged on as a user # profile.feature:4 /^I am logged on as an admin$/ # profile_steps.rb:6 NOT MATCHED BY ANY STEPS /^I am logged on as an organizer$/ # events_steps.rb:6 Given I am logged on as an organizer # events.feature:10 . . .
  82. REMOVE Unused Steps Given(/^I am logged on as a user$/)

    do user = FactoryGirl.create(:person) login_user(user) end Given(/^I am logged on as an admin$/) do # Not sure what to do with this just yet end $: cat features/step_definitions/profile_steps.rb
  83. AT HIREOLOGY STATE OF CUCUMBER. 144 scenarios (144 passed) 915

    steps (915 passed) 7m37.653s # of Scenarios
  84. AT HIREOLOGY STATE OF CUCUMBER. 144 scenarios (144 passed) 915

    steps (915 passed) 7m37.653s # of Scenarios Total Flog Value 3504 for step definitions 773 for page objects
  85. AT HIREOLOGY STATE OF CUCUMBER. 144 scenarios (144 passed) 915

    steps (915 passed) 7m37.653s # of Scenarios Total Flog Value 3504 for step definitions 773 for page objects # of Files 48 step definition files 51 page object files 77 feature files
  86. SIMULATING External Services ... When(/^I submit the order$/) do VCR.use_cassette(‘purchasing

    an item’) do Pages.make(Checkout::OrderPreview).submit end end ...
  87. RUN TESTS in Isolation ... When(/^I submit the order$/) do

    VCR.use_cassette(‘purchasing an item’) do Pages.make(Checkout::OrderPreview).submit end end ...
  88. CUCUMBER IS NOT A TOOL FOR TESTING APPLICATIONS. CUCUMBER IS

    A PHILOSOPHY FOR COMMUNICATING REQUIREMENTS. ~ Robert C. Martin (Uncle Bob) “
  89. Always start with acceptance tests Scenarios are state transitions Don’t

    test the UI, verify the behavior Scenarios have structure Use free-form text to describe scenarios Use cucumber for discovering requirements SUMMARY FOR GHERKIN
  90. Use factories to set up your data Keep step definitions

    stateless Reset the DB to a known state Find DOM elements by IDs, not by labels Abstract UI volatility into page objects Simulate external services in your tests SUMMARY FOR STEP DEFINITIONS