SlideShare ist ein Scribd-Unternehmen logo
1 von 48
Downloaden Sie, um offline zu lesen
Writing Better
Domain Oriented
  Cucumber
   Features
   Amir Barylko
Better Cucumber Features


Who am I?
•   Architect

•   Developer

•   Mentor

•   Great cook

•   The one who’s entertaining you for the next hour!
Behavior Driven Dev.


           Text
            Text




                   The rSpec Book
Amir Barylko - Better Cucumber Features


Why Projects Fail?
• Delivering   late or over budget

• Delivering   the wrong thing

• Unstable   in production

• Costly   to maintain
Amir Barylko - Better Cucumber Features


Improve Quality
• Unit Testing

• Integration Testing

• Acceptance Testing
Amir Barylko - Better Cucumber Features


BDD
• Implementing    an application

• by   describing its behavior

• from   the perspective of the stakeholder
Amir Barylko - Better Cucumber Features


Outside In Approach


       BDD                TDD
Amir Barylko - Better Cucumber Features


Test First
• Write   a test before any line of code

• Write minimum amount of code to make
 the test pass

• Refactor   code to eliminate “smells”
Cucumber
Amir Barylko - Better Cucumber Features


Gherkin DSL
•   Business readable DSL

•   Flush out requirements

•   Documentation

•   Automated testing

•   Used by Cucumber,
    SpecFlow, jBehave
Amir Barylko - Better Cucumber Features


Gherkin Keywords
• Feature        • Then

• Scenario       • And

• Given          • But

• When
Amir Barylko - Better Cucumber Features


Features
Feature: Listing projects
  As a user                           Free         text!
  I Want to see the list of projects
  So I can choose one to see the details

  Scenario: List all projects
     (steps here to implement scenario)

  Scenario: No projects are available
     (steps here to implement scenario)
Amir Barylko - Better Cucumber Features


Scenario
Scenario: List all projects
  Given I'm logged in                               Step 1



  And    I have some projects stored                Step 2


  When   I browse the projects                      Step 3



  Then   I should see all of them listed            Step 4
Amir Barylko - Better Cucumber Features


Running Features
•   Parse the feature

    •   Parse the scenario

        •   For each scenario

            •   Find a step implementation

            •   Execute the code
Amir Barylko - Better Cucumber Features


Matching Step
• Matching   regular expression
 Given I have some projects stored             Feature File




 Given /^I have some projects stored$/
                                              Step Def File
Amir Barylko - Better Cucumber Features


Step
Given /^I have some projects stored$/ do
  projects = 10.times { random_valid_project }
  fake_response = create_response(projects)
  FakeWeb.register_uri(....)
end
                                          Plain
                                          Ruby!
Expressive Scenarios
Amir Barylko - Better Cucumber Features


What we want?
•   Readability

•   Ubiquitous Language

•   Consistent use of terminology

•   Express natural business intent

•   Avoid technical aspects
Amir Barylko - Better Cucumber Features


Imperative style
Scenario: Redirect user to originally requested page
  Given a User "dave" exists with password "secret"
  And    I am not logged in
  When   I navigate to the home page
  Then   I am redirected to the login form
  When   I fill in "Username" with "dave"
  And    I fill in "Password" with "secret"
  And    I press "Login"
Amir Barylko - Better Cucumber Features


What’s the problem?
•   Who needs the passwords?

•   Tightly coupled to page implementation

•   Lacks domain language

•   Brittle tests

•   Does not tell a story (boring)
Amir Barylko - Better Cucumber Features


Declarative style
Scenario: Redirect user to originally requested page

  Given I am an authenticated user

  When   I attempt to view restricted content

  Then   I am presented with a login form

  When   I authenticated with valid credentials

  Then   I should be shown the restricted content
Amir Barylko - Better Cucumber Features


Declarative vs Imperative
• Imperative   is associated to “how” to do it

• Declarative   is associated to “what” we
 want

• Where’s   the boundary?
Amir Barylko - Better Cucumber Features


Too abstract?
Scenario: The whole system
 Given the system exists
 When   I use it
 Then   it should work, perfectly
Amir Barylko - Better Cucumber Features


Background steps
•   Steps may have some degree of repetition

•   Because they start with the same “state”

•   So they share the first X steps
Amir Barylko - Better Cucumber Features


Similar scenarios
Scenario: Change Password
  Given I am logged in
  And    I choose to change my password
  When   I enter a new password
  Then   my password should be changed


Scenario: Change Password with same credentials
  Given I am logged in
  And    I choose to change my password
  When   I enter the same password
  Then   I should see an error message explaining the problem
Amir Barylko - Better Cucumber Features


Create Background
Background: I want to change my password
  Given I am logged in
  And    I choose to change my password


Scenario: Change Password
  When   I enter a new password
  Then   my password should be changed


Scenario: Change Password with same credentials
  When   I enter the same password
  Then   I should see an error message explaining the problem
Amir Barylko - Better Cucumber Features


Using Tables
•   Sometimes data is hard to put in a step

•   with multiple entries

Scenario: Listing movies
    Given the movie “Blazing saddles” released “7 Feb 1974”
    And   the movie “Young Frankenstein” released “15 Dec 1974”
    And   the movie “The Producers” released “10 Nov 1968”
Amir Barylko - Better Cucumber Features


That’s boring!
•   Express data in tabular form

Scenario: Listing movies
    Given these movies:
      | title              | release        |
      | Blazing saddles    | 7 Feb 1974     |
      | Young Frankenstein | 15 Dec 1974 |
      | The Producers      | 10 Nov 1968 |
Amir Barylko - Better Cucumber Features


Or just a list
•   Don’t use the header

Scenario: Listing movies
    Given these movies:
      | Blazing saddles    |
      | Young Frankenstein |
      | The Producers      |
Amir Barylko - Better Cucumber Features


Why the detail though?
•   Do you really need the list?


Scenario: Listing movies
    Given I have some movies stored
    When   I browse the list
    Then   I should see the complete collection
Amir Barylko - Better Cucumber Features


Leaky Scenarios
•   Each scenario leaves the system in a
    particular state

•   The state has to be cleaned up for the next
    scenario

•   Otherwise it will “leak” into it

•   One scenario should not depend on another
Amir Barylko - Better Cucumber Features


Generating data
•   Use a framework to generate valid data

•   FactoryGirl is a very good option

    •   FactoryGirl.create(:customer)


    •   FactoryGirl.create(:invalid_bank_accout)


•   Faker will help you to generate fake data
Amir Barylko - Better Cucumber Features


Transforms
•   Steps can have arguments

•   Though regular expression they don’t always
    show intent

•   And also we may need to “reuse” them
Amir Barylko - Better Cucumber Features


Steps with arguments
Given /^I search for a movie “([^"]*)”$/ do |name|
  .... # some code here
end



Given /^I have a movie called “([^"]*)”$/ do |name|
 .... # some code here
end
Amir Barylko - Better Cucumber Features


Capture the argument
Given /^I search for a movie “(#{MOVIE_NAME})”$/ do |name|
  .... # some code here
end



MOVIE_NAME = Transform /^([^"]+)$/ do | movie_name |
  movie_name.downcase
end
Amir Barylko - Better Cucumber Features


Helpers
•   Helpers are a great tool to encapsulate
    common functionality

•   Or to help describe better our intention

•   and to avoid looking at ugly code
Amir Barylko - Better Cucumber Features


Current Instance
•   The World is created for each scenario

•   Instance variables have to be set

•   Instead we can use a helper method

•   to store/create the resource
Amir Barylko - Better Cucumber Features


Helper Class
module ProjectHelper

  def current_project(project = nil)
    @current_project ||= project
  end

  def project_list_page
    @project_list_page ||= ProjectListPage.new
  end

end

World(ProjectHelper)
Amir Barylko - Better Cucumber Features


Custom matchers
RSpec::Matchers.define :match_stored_projects do
  match do |actual|
    actual == Project.all.map { ... }
  end

 failure_message_for_should do |actual|
   "The projects in the page should match...n" +
   "The page contains #{actual}' n" +
   "But the storage contains #{@expected}"
 end

end
Amir Barylko - Better Cucumber Features


Page Objects
•   The steps rely on the HTML implementation

•   Searching for elements can be repetitive

•   or ugly

•   and not always show intention
Amir Barylko - Better Cucumber Features


What can we do?
Then /^I should see the complete list of projects$/ do
  actual = all(:css, "#projects tbody tr")
•   .map { |tr| tr.all("td").map(&:text) }
    .map { |cells| ... }
  expected = Project.all.map { |p| ... }
  actual.should == expected
end
Amir Barylko - Better Cucumber Features


Abstraction!
class ProjectListPage
    include PageObject
•
      def projects
        all(:css, "#projects tr").
          drop(1). #drop the header
          map { |r| r.all(:css, 'td').map(&:text) }.
          map { |r| Project.new(...) }
      end
end
Amir Barylko - Better Cucumber Features


Nicer steps
Then /^I should see the complete list of projects$/ do
  projects_page.list.should == stored_projects
•
end

  Page Object                                  Helper
Amir Barylko - Better Cucumber Features


With a custom matcher
Then /^I should see the complete list of projects$/ do
  projects_page.should list_stored_projects
•
end

                                   Custom
                                   Matcher
Summary
Amir Barylko - Better Cucumber Features


Next steps
•   Focus your scenarios on “what” not “how”

•   Read about scenario outlines

•   Follow “the Cucumber book” practices

•   Learn more about page objects pattern

•   Start with a simple project
Amir Barylko - Better Cucumber Features


Resources
• Email: amir@barylko.com,

• Twitter: @abarylko

• Blog: http://orthocoders.com

• Website: http://maventhought.com
Amir Barylko - Better Cucumber Features


Resources II

Weitere ähnliche Inhalte

Was ist angesagt?

Advanced Skinning & Styling for Android
Advanced Skinning & Styling for AndroidAdvanced Skinning & Styling for Android
Advanced Skinning & Styling for Android
cephus07
 
Technical and symbolic codes moving image
Technical and symbolic codes   moving imageTechnical and symbolic codes   moving image
Technical and symbolic codes moving image
jennymann
 

Was ist angesagt? (10)

creative commons about license only with three colors
creative commons about license only with three colorscreative commons about license only with three colors
creative commons about license only with three colors
 
Deep Dive into Flex Mobile Item Renderers
Deep Dive into Flex Mobile Item RenderersDeep Dive into Flex Mobile Item Renderers
Deep Dive into Flex Mobile Item Renderers
 
Gamemaker - More core objects
Gamemaker - More core objectsGamemaker - More core objects
Gamemaker - More core objects
 
Software Engineering Thailand: Programming with Scala
Software Engineering Thailand: Programming with ScalaSoftware Engineering Thailand: Programming with Scala
Software Engineering Thailand: Programming with Scala
 
Call Control Power Tools with Adhearsion
Call Control Power Tools with AdhearsionCall Control Power Tools with Adhearsion
Call Control Power Tools with Adhearsion
 
Advanced Skinning & Styling for Android
Advanced Skinning & Styling for AndroidAdvanced Skinning & Styling for Android
Advanced Skinning & Styling for Android
 
Testing Alexa Skill
Testing Alexa SkillTesting Alexa Skill
Testing Alexa Skill
 
Wd hw 1
Wd hw 1Wd hw 1
Wd hw 1
 
Technical and symbolic_codes_-_moving_image
Technical and symbolic_codes_-_moving_imageTechnical and symbolic_codes_-_moving_image
Technical and symbolic_codes_-_moving_image
 
Technical and symbolic codes moving image
Technical and symbolic codes   moving imageTechnical and symbolic codes   moving image
Technical and symbolic codes moving image
 

Ähnlich wie DevTeach12-betterspecs

prdc10-Bdd-real-world
prdc10-Bdd-real-worldprdc10-Bdd-real-world
prdc10-Bdd-real-world
Amir Barylko
 
Behaviour driven development present
Behaviour driven development presentBehaviour driven development present
Behaviour driven development present
Raul Panjiyar
 
Behavior Driven Development, Ruby Style
Behavior Driven Development, Ruby StyleBehavior Driven Development, Ruby Style
Behavior Driven Development, Ruby Style
Bozhidar Batsov
 

Ähnlich wie DevTeach12-betterspecs (20)

PRDCW-advanced-design-patterns
PRDCW-advanced-design-patternsPRDCW-advanced-design-patterns
PRDCW-advanced-design-patterns
 
PRDC12 advanced design patterns
PRDC12 advanced design patternsPRDC12 advanced design patterns
PRDC12 advanced design patterns
 
sdec11-Advanced-design-patterns
sdec11-Advanced-design-patternssdec11-Advanced-design-patterns
sdec11-Advanced-design-patterns
 
Page objects pattern
Page objects patternPage objects pattern
Page objects pattern
 
Page-objects-pattern
Page-objects-patternPage-objects-pattern
Page-objects-pattern
 
Automated UI test on mobile - with Cucumber/Calabash
Automated UI test on mobile - with Cucumber/CalabashAutomated UI test on mobile - with Cucumber/Calabash
Automated UI test on mobile - with Cucumber/Calabash
 
YEG-UG-Capybara
YEG-UG-CapybaraYEG-UG-Capybara
YEG-UG-Capybara
 
Outside-in Development with Cucumber and Rspec
Outside-in Development with Cucumber and RspecOutside-in Development with Cucumber and Rspec
Outside-in Development with Cucumber and Rspec
 
Cucumber
CucumberCucumber
Cucumber
 
prdc10-Bdd-real-world
prdc10-Bdd-real-worldprdc10-Bdd-real-world
prdc10-Bdd-real-world
 
Agile requirements
Agile requirementsAgile requirements
Agile requirements
 
2012 regina TC - 103 quality driven
2012 regina TC - 103 quality driven2012 regina TC - 103 quality driven
2012 regina TC - 103 quality driven
 
Behaviour driven development present
Behaviour driven development presentBehaviour driven development present
Behaviour driven development present
 
Nuget
NugetNuget
Nuget
 
Cucumber
CucumberCucumber
Cucumber
 
CUCUMBER - Making BDD Fun
CUCUMBER - Making BDD FunCUCUMBER - Making BDD Fun
CUCUMBER - Making BDD Fun
 
Behavior Driven Development, Ruby Style
Behavior Driven Development, Ruby StyleBehavior Driven Development, Ruby Style
Behavior Driven Development, Ruby Style
 
Cucumber Ru09 Web
Cucumber Ru09 WebCucumber Ru09 Web
Cucumber Ru09 Web
 
Cucumber testing
Cucumber testingCucumber testing
Cucumber testing
 
Cucumber testing
Cucumber testingCucumber testing
Cucumber testing
 

Mehr von Amir Barylko

Beutiful javascript with coffeescript
Beutiful javascript with coffeescriptBeutiful javascript with coffeescript
Beutiful javascript with coffeescript
Amir Barylko
 

Mehr von Amir Barylko (20)

Functional converter project
Functional converter projectFunctional converter project
Functional converter project
 
Elm: delightful web development
Elm: delightful web developmentElm: delightful web development
Elm: delightful web development
 
Dot Net Core
Dot Net CoreDot Net Core
Dot Net Core
 
No estimates
No estimatesNo estimates
No estimates
 
User stories deep dive
User stories deep diveUser stories deep dive
User stories deep dive
 
Coderetreat hosting training
Coderetreat hosting trainingCoderetreat hosting training
Coderetreat hosting training
 
There's no charge for (functional) awesomeness
There's no charge for (functional) awesomenessThere's no charge for (functional) awesomeness
There's no charge for (functional) awesomeness
 
What's new in c# 6
What's new in c# 6What's new in c# 6
What's new in c# 6
 
Productive teams
Productive teamsProductive teams
Productive teams
 
Who killed object oriented design?
Who killed object oriented design?Who killed object oriented design?
Who killed object oriented design?
 
From coach to owner - What I learned from the other side
From coach to owner - What I learned from the other sideFrom coach to owner - What I learned from the other side
From coach to owner - What I learned from the other side
 
Communication is the Key to Teamwork and productivity
Communication is the Key to Teamwork and productivityCommunication is the Key to Teamwork and productivity
Communication is the Key to Teamwork and productivity
 
Acceptance Test Driven Development
Acceptance Test Driven DevelopmentAcceptance Test Driven Development
Acceptance Test Driven Development
 
Refactoring
RefactoringRefactoring
Refactoring
 
Agile requirements
Agile requirementsAgile requirements
Agile requirements
 
Agile teams and responsibilities
Agile teams and responsibilitiesAgile teams and responsibilities
Agile teams and responsibilities
 
Refactoring
RefactoringRefactoring
Refactoring
 
Beutiful javascript with coffeescript
Beutiful javascript with coffeescriptBeutiful javascript with coffeescript
Beutiful javascript with coffeescript
 
Sass & bootstrap
Sass & bootstrapSass & bootstrap
Sass & bootstrap
 
SDEC12 Beautiful javascript with coffeescript
SDEC12 Beautiful javascript with coffeescriptSDEC12 Beautiful javascript with coffeescript
SDEC12 Beautiful javascript with coffeescript
 

Kürzlich hochgeladen

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Kürzlich hochgeladen (20)

GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 

DevTeach12-betterspecs

  • 1. Writing Better Domain Oriented Cucumber Features Amir Barylko
  • 2. Better Cucumber Features Who am I? • Architect • Developer • Mentor • Great cook • The one who’s entertaining you for the next hour!
  • 3. Behavior Driven Dev. Text Text The rSpec Book
  • 4. Amir Barylko - Better Cucumber Features Why Projects Fail? • Delivering late or over budget • Delivering the wrong thing • Unstable in production • Costly to maintain
  • 5. Amir Barylko - Better Cucumber Features Improve Quality • Unit Testing • Integration Testing • Acceptance Testing
  • 6. Amir Barylko - Better Cucumber Features BDD • Implementing an application • by describing its behavior • from the perspective of the stakeholder
  • 7. Amir Barylko - Better Cucumber Features Outside In Approach BDD TDD
  • 8. Amir Barylko - Better Cucumber Features Test First • Write a test before any line of code • Write minimum amount of code to make the test pass • Refactor code to eliminate “smells”
  • 10. Amir Barylko - Better Cucumber Features Gherkin DSL • Business readable DSL • Flush out requirements • Documentation • Automated testing • Used by Cucumber, SpecFlow, jBehave
  • 11. Amir Barylko - Better Cucumber Features Gherkin Keywords • Feature • Then • Scenario • And • Given • But • When
  • 12. Amir Barylko - Better Cucumber Features Features Feature: Listing projects As a user Free text! I Want to see the list of projects So I can choose one to see the details Scenario: List all projects (steps here to implement scenario) Scenario: No projects are available (steps here to implement scenario)
  • 13. Amir Barylko - Better Cucumber Features Scenario Scenario: List all projects Given I'm logged in Step 1 And I have some projects stored Step 2 When I browse the projects Step 3 Then I should see all of them listed Step 4
  • 14. Amir Barylko - Better Cucumber Features Running Features • Parse the feature • Parse the scenario • For each scenario • Find a step implementation • Execute the code
  • 15. Amir Barylko - Better Cucumber Features Matching Step • Matching regular expression Given I have some projects stored Feature File Given /^I have some projects stored$/ Step Def File
  • 16. Amir Barylko - Better Cucumber Features Step Given /^I have some projects stored$/ do projects = 10.times { random_valid_project } fake_response = create_response(projects) FakeWeb.register_uri(....) end Plain Ruby!
  • 18. Amir Barylko - Better Cucumber Features What we want? • Readability • Ubiquitous Language • Consistent use of terminology • Express natural business intent • Avoid technical aspects
  • 19. Amir Barylko - Better Cucumber Features Imperative style Scenario: Redirect user to originally requested page Given a User "dave" exists with password "secret" And I am not logged in When I navigate to the home page Then I am redirected to the login form When I fill in "Username" with "dave" And I fill in "Password" with "secret" And I press "Login"
  • 20. Amir Barylko - Better Cucumber Features What’s the problem? • Who needs the passwords? • Tightly coupled to page implementation • Lacks domain language • Brittle tests • Does not tell a story (boring)
  • 21. Amir Barylko - Better Cucumber Features Declarative style Scenario: Redirect user to originally requested page Given I am an authenticated user When I attempt to view restricted content Then I am presented with a login form When I authenticated with valid credentials Then I should be shown the restricted content
  • 22. Amir Barylko - Better Cucumber Features Declarative vs Imperative • Imperative is associated to “how” to do it • Declarative is associated to “what” we want • Where’s the boundary?
  • 23. Amir Barylko - Better Cucumber Features Too abstract? Scenario: The whole system Given the system exists When I use it Then it should work, perfectly
  • 24. Amir Barylko - Better Cucumber Features Background steps • Steps may have some degree of repetition • Because they start with the same “state” • So they share the first X steps
  • 25. Amir Barylko - Better Cucumber Features Similar scenarios Scenario: Change Password Given I am logged in And I choose to change my password When I enter a new password Then my password should be changed Scenario: Change Password with same credentials Given I am logged in And I choose to change my password When I enter the same password Then I should see an error message explaining the problem
  • 26. Amir Barylko - Better Cucumber Features Create Background Background: I want to change my password Given I am logged in And I choose to change my password Scenario: Change Password When I enter a new password Then my password should be changed Scenario: Change Password with same credentials When I enter the same password Then I should see an error message explaining the problem
  • 27. Amir Barylko - Better Cucumber Features Using Tables • Sometimes data is hard to put in a step • with multiple entries Scenario: Listing movies Given the movie “Blazing saddles” released “7 Feb 1974” And the movie “Young Frankenstein” released “15 Dec 1974” And the movie “The Producers” released “10 Nov 1968”
  • 28. Amir Barylko - Better Cucumber Features That’s boring! • Express data in tabular form Scenario: Listing movies Given these movies: | title | release | | Blazing saddles | 7 Feb 1974 | | Young Frankenstein | 15 Dec 1974 | | The Producers | 10 Nov 1968 |
  • 29. Amir Barylko - Better Cucumber Features Or just a list • Don’t use the header Scenario: Listing movies Given these movies: | Blazing saddles | | Young Frankenstein | | The Producers |
  • 30. Amir Barylko - Better Cucumber Features Why the detail though? • Do you really need the list? Scenario: Listing movies Given I have some movies stored When I browse the list Then I should see the complete collection
  • 31. Amir Barylko - Better Cucumber Features Leaky Scenarios • Each scenario leaves the system in a particular state • The state has to be cleaned up for the next scenario • Otherwise it will “leak” into it • One scenario should not depend on another
  • 32. Amir Barylko - Better Cucumber Features Generating data • Use a framework to generate valid data • FactoryGirl is a very good option • FactoryGirl.create(:customer) • FactoryGirl.create(:invalid_bank_accout) • Faker will help you to generate fake data
  • 33. Amir Barylko - Better Cucumber Features Transforms • Steps can have arguments • Though regular expression they don’t always show intent • And also we may need to “reuse” them
  • 34. Amir Barylko - Better Cucumber Features Steps with arguments Given /^I search for a movie “([^"]*)”$/ do |name| .... # some code here end Given /^I have a movie called “([^"]*)”$/ do |name| .... # some code here end
  • 35. Amir Barylko - Better Cucumber Features Capture the argument Given /^I search for a movie “(#{MOVIE_NAME})”$/ do |name| .... # some code here end MOVIE_NAME = Transform /^([^"]+)$/ do | movie_name | movie_name.downcase end
  • 36. Amir Barylko - Better Cucumber Features Helpers • Helpers are a great tool to encapsulate common functionality • Or to help describe better our intention • and to avoid looking at ugly code
  • 37. Amir Barylko - Better Cucumber Features Current Instance • The World is created for each scenario • Instance variables have to be set • Instead we can use a helper method • to store/create the resource
  • 38. Amir Barylko - Better Cucumber Features Helper Class module ProjectHelper def current_project(project = nil) @current_project ||= project end def project_list_page @project_list_page ||= ProjectListPage.new end end World(ProjectHelper)
  • 39. Amir Barylko - Better Cucumber Features Custom matchers RSpec::Matchers.define :match_stored_projects do match do |actual| actual == Project.all.map { ... } end failure_message_for_should do |actual| "The projects in the page should match...n" + "The page contains #{actual}' n" + "But the storage contains #{@expected}" end end
  • 40. Amir Barylko - Better Cucumber Features Page Objects • The steps rely on the HTML implementation • Searching for elements can be repetitive • or ugly • and not always show intention
  • 41. Amir Barylko - Better Cucumber Features What can we do? Then /^I should see the complete list of projects$/ do actual = all(:css, "#projects tbody tr") • .map { |tr| tr.all("td").map(&:text) } .map { |cells| ... } expected = Project.all.map { |p| ... } actual.should == expected end
  • 42. Amir Barylko - Better Cucumber Features Abstraction! class ProjectListPage include PageObject • def projects all(:css, "#projects tr"). drop(1). #drop the header map { |r| r.all(:css, 'td').map(&:text) }. map { |r| Project.new(...) } end end
  • 43. Amir Barylko - Better Cucumber Features Nicer steps Then /^I should see the complete list of projects$/ do projects_page.list.should == stored_projects • end Page Object Helper
  • 44. Amir Barylko - Better Cucumber Features With a custom matcher Then /^I should see the complete list of projects$/ do projects_page.should list_stored_projects • end Custom Matcher
  • 46. Amir Barylko - Better Cucumber Features Next steps • Focus your scenarios on “what” not “how” • Read about scenario outlines • Follow “the Cucumber book” practices • Learn more about page objects pattern • Start with a simple project
  • 47. Amir Barylko - Better Cucumber Features Resources • Email: amir@barylko.com, • Twitter: @abarylko • Blog: http://orthocoders.com • Website: http://maventhought.com
  • 48. Amir Barylko - Better Cucumber Features Resources II