A friend is using Cucumber to run his Behavior Driven Development and it isn’t turning out to be the elegance and joy promised on ‘the can’ so we got together to see what the issues were and how to lessen the problems he was having.
In short, the code looked a lot like this:
Given /Some starting state/ do lots of code to setup state end When /Some condition/ do lots of code to exercise condition end Then /Some behavior/ do lots of code to verify behavior end
There was a lot of magic going on with variables being defined in one feature file and referenced across multiple feature steps and some steps even introducing more variables. The net effect was code that was tossed together, difficult to keep dry and impossible to refactor, like a cucumber salad where your task was to take the pieces out and reconstitute the whole original ingredients. It was quite a nightmare and it reminded me of the song from The Simpsons where they form a conga line and sing “You Don’t Win Friends With Salad.” So what could he do to clean this up and not lose friends with this salad ?
A simple approach is to create a fixture class that represents the application, web site or service under test and then only delegate to that fixture class in Cucumber related files. This approach keeps logic out of Cucumber files, the code in Classes where it can be reused, kept dry and refactored more easily. It is also easier to understand the code because it is all in one place. You can also use the fixture in other scripts to automate other tasks you might have.
For example, here is some Cucumber that uses the fixture approach:
Given /Signed In User is on their profile page/ do @theWebSite.open .sign_in('u', 'p') .navigate_to_profile_page end When /Changing Password/ do @theWebSite.select_change_password end Then /Change Password Form is Shown/ do @theWebSite.has_password_form? end
Remember, you don’t win friends with salad !