Using Cucumber Step Argument Transforms
For Fun and Profit
In a recent project that is tested with Cucumber we were using „within“ steps with CSS selectors. Though this isn’t basically considered a good idea I’d say it made sense for us, because we had to select specific parts of the page. Cuking it like that, our steps usually looked something like this:
Scenario: Edit something
Given there is something
And another something
When I go to the page of somethings
And I follow "edit" within "ul.somethings li:nth-child(1)"
Then I should be on the edit page for "something"
Besides looking just ugly, CSS selectors also don’t offer any business value and are likely to change. Cucumber’s Step Argument Transforms can help you avoid that by refactoring common operations.
Transforms are defined with the Transform keyword and can be a part of your step definition files. Cucumber matches
the captures in your steps (i.e. the 1st something) against the defined transforms. If the regexp matches, it yields
the transformed value as an argument to the step definition block. This sounds complicated, so here’s an example:
Transform /^the (\d+)(?:st|nd|rd|th) something$/ do |num|
"ul.somethings li:nth-child(#{num})"
end
This transform allows us to refactor the scenario above to be more readable and maintainable:
Scenario: Edit something
…
When I go to the page of somethings
And I follow "edit" within "the 1st something"
…
We can even abstract this a little further and make it usable on a common level:
Transform /^the (\d+)(?:st|nd|rd|th) (.+)$/ do |num, type|
"ul.#{type.pluralize} li:nth-child(#{num})"
end
This is just a basic example of how this often unknown Cucumber feature might help you to refactor your step definitions. For more information and decent examples check out the wiki page on Step Argument Transforms.