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})"

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})"

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.