Slide 1

Slide 1 text

BAD AIN’T YOU’RE JUST DOING IT WRONG… CUCUMBER Attila Domokos
 @adomokos

Slide 2

Slide 2 text

7:20 AM Leaving the House

Slide 3

Slide 3 text

7:30 AM Train Kept a Rollin’

Slide 4

Slide 4 text

7:40 AM On the Train

Slide 5

Slide 5 text

8:20 AM Walking to the Office

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

OUR PRODUCT TEAM

Slide 8

Slide 8 text

CFP APP Your Profile

Slide 9

Slide 9 text

BDD Workflow Unit Test Acceptance Test red green refactor red green refactor start

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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 …

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

CUCUMBER Components Gherkin Application Cucumber

Slide 14

Slide 14 text

CUCUMBER Components Feature files with scenarios Gherkin Application Cucumber

Slide 15

Slide 15 text

CUCUMBER Components Feature files with scenarios Step definitions and automation Gherkin Application Cucumber

Slide 16

Slide 16 text

CUCUMBER Components Feature files with scenarios Step definitions and automation Application under test Gherkin Application Cucumber

Slide 17

Slide 17 text

YOU MIGHT BE DOING IT WRONG CUCUMBER AIN’T BAD. GHERKIN BEST PRACTICES CUCUMBER STEP DEFINITION RECIPES

Slide 18

Slide 18 text

YOU MIGHT BE DOING IT WRONG CUCUMBER AIN’T BAD. GHERKIN BEST PRACTICES

Slide 19

Slide 19 text

CFP APP Your Profile

Slide 20

Slide 20 text

CFP APP Your Profile

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

STATE Transition Pre-State Post-State Trigger

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

CFP APP Your Profile

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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 When I submit the profile form Then my is updated Examples: | subject | | demographics info | | bio |

Slide 48

Slide 48 text

YOU MIGHT BE DOING IT WRONG CUCUMBER AIN’T BAD. GHERKIN BEST PRACTICES

Slide 49

Slide 49 text

YOU MIGHT BE DOING IT WRONG CUCUMBER AIN’T BAD. GHERKIN BEST PRACTICES CUCUMBER STEP DEFINITION RECIPES

Slide 50

Slide 50 text

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'

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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'

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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'

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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'

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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'

Slide 64

Slide 64 text

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'

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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 When I submit the profile form Then my is updated Examples: | subject | | demographics info | Undefined step: "I set up my demographics info" | bio | Undefined step: "I set up my bio"

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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 When I submit the profile form Then my is updated Examples: | subject | | demographics info | Undefined step: "I submit the profile form" | bio | Undefined step: "I set up my bio"

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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 When I submit the profile form Then my is updated Examples: | subject | | demographics info | Undefined step: "my demographics info is updated" | bio | Undefined step: "I set up my bio"

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

USE ID Not Label

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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 When I submit the profile form Then my is updated Examples: | subject | | demographics info | Undefined step: "my demographics info is updated" | bio | Undefined step: "I set up my bio"

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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 When I submit the profile form Then my is updated Examples: | subject | | demographics info | | bio | Undefined step: "I set up my bio"

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

INTRODUCING the Page Object. Page

Slide 86

Slide 86 text

INTRODUCING the Page Object. Page

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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 When I submit the profile form Then my is updated Examples: | subject | | demographics info | | bio | Undefined step: "I set up my bio"

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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 When I submit the profile form Then my is updated Examples: | subject | | demographics info | | bio |

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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 When I submit the profile form Then my is updated Examples: | subject | | demographics info | | bio |

Slide 100

Slide 100 text

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 When I submit the profile form Then my 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 is updated' | bio |

Slide 101

Slide 101 text

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 When I submit the profile form Then my is updated Examples: | subject | | demographics info | | bio | $: cat features/profile.feature

Slide 102

Slide 102 text

AFTER STEP Pause AfterStep(‘@pause’) do print “Press Return to continue…” STDIN.getc end $: cat features/support/hooks.rb

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

AT HIREOLOGY STATE OF CUCUMBER.

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

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

Slide 110

Slide 110 text

TALKING to External Services Background Check API Payment Gateway Other APIs

Slide 111

Slide 111 text

SIMULATING External Services ... When(/^I submit the order$/) do VCR.use_cassette(‘purchasing an item’) do Pages.make(Checkout::OrderPreview).submit end end ...

Slide 112

Slide 112 text

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

Slide 113

Slide 113 text

CUCUMBER is Not For Testing

Slide 114

Slide 114 text

SAD Realization

Slide 115

Slide 115 text

CUCUMBER IS NOT A TOOL FOR TESTING APPLICATIONS. CUCUMBER IS A PHILOSOPHY FOR COMMUNICATING REQUIREMENTS. ~ Robert C. Martin (Uncle Bob) “

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

18:00 PM READY TO GO HOME

Slide 119

Slide 119 text

FOR YOUR ATTENTION THANK YOU EXIT

Slide 120

Slide 120 text

TWITTER TWITTER.COM/ADOMOKOS BLOG ADOMOKOS.COM GITHUB GITHUB.COM/ADOMOKOS MY SOCIAL LINKS ATTILA DOMOKOS.