It's all about abstraction
# nice_cucumber.feature Scenario: Artist creates an art work Given I am a registered artist And I follow the add new artwork link from the dashboard When I fill the form with the artwork data And I upload a picture Then I should see a confirmation message telling me that the artwork was added to my collection
# ugly_cucumber.feature Scenario: Artist creates an art work Given I am a registered artist And I am on my dashboard And I follow "Add an artwork" within "#dashboard" When I fill in "Title" with "The Arnolfini Portrait" And I fill in "Description" with "A nice portrait." And I select "Painting" from "Category" And I attach "arnolfini.jpg" to "Select picture" And I press "Create" Then I should see "The Arnolfini Portrait was successfully added to your art collection."
Or even worse:
# zomg_steak.rb scenario do create_artist login: "jdoe" login_as "jdoe" visit dashboard_path within(:css, '#dashboard') do click 'Add an artwork' end fill_in "title", with: "The Arnolfini Portrait" fill_in "Description", with: "A nice portrait." select "Painting", from: "Category" attach_file("Select picture", File.expand_path("arnolfini.jpg")) click "Create" page.should have_css("#flash.notice", :text => "The Arnolfini Portrait was successfully added to your art collection.") end
I could stop writing this post right now, the examples speak for themselves.
In case you don't think so, please watch this presentation NOW: Refuctoring your cukes (Skills Matter, WHY U USE TABLES AND PRIVATE VIMEO VIDEOS?)
It's all about abstraction
Writing scenarios this way (the first one) helps you separate features from code. You don't have to think about what fields the form will have, or the id or class of the div, just focus on describing the feature (the business value).
Plus, do you know a best way to transfer the knowledge of a feature than just describing it? (With the benefit that you actually get executable code)
Think about it, are you describing a feature or are you using Cucumber as an expensive Capybara wrapper? If you're doing the latter you're probably better off using Steak (AKA some aliases for RSpec) or Coulda or TU or whatever you want.
Cucumber has always been criticized because maintaining steps has always been a PITA. But, do we need to write cross-feature steps? You don't need to reuse them everywhere, just use the words that better describe a behavior for each case.
The path to better Cukes
web_steps.rb(you just need a Capybara cheatsheet)
- Stop using Pickle (creating an instance variable is not that hard)
- Start writing beautiful scenarios!
I'd love to hear what people think about this, so please, leave your comments!