aslakhellesoy / cucumber

BDD that talks to domain experts first and code second

Home | Edit | New

Step Argument Transforms

Step argument transforms help your step definitions be more DRY. You can use the Transform method to register a regular expression along with a code block. Before captured Regexp groups get yielded as arguments to step definitions, an attempt is made to match them against any registered Transform. If there is a match, the return value of the block supplied with the transform is yielded as the step definition argument instead.

It’s recommended that you put Transform code in the same file as the step definitions using them. It becomes easier to navigate your code that way. Here is an example:

# features/step_definitions/user_steps.rb

Transform /^user \w+$/ do |step_arg|
  User.find_by_username /(\w+)$/.match(step_arg)[0]
end

Then /^(user \w+) should be friends with (user \w+)$/ do |user, friend|
  user.should be_friends_with(friend)
end
# features/befriending.feature
Scenario: befriending
  Given ...
  When ...
  Then user larrytheliquid should be friends with user dastels

Note that sometimes you may not need to parse the entire step_arg and may only care about a specific Regexp capture group being matched. For this more common case, you can use an optional syntax for Transform where the block supplied has arguments that correspond to capture groups in the registered Regexp:

Transform /^user (\w+)$/ do |username|
  User.find_by_username username
end

One key thing to remember is to provide some contextual data like “user” so you don’t end up transforming every single argument to a step definition. See this blog post for a more detailed explanation and examples.

Transforming tables

Step argument transforms can also be used with tables. A table is matched via a comma-delimited list of the column headers and the ‘table:’ prefix:

Scenario: setting up via table
  Given ...
  When ...
  Then I should have
    | name  | age |
    | corey | 36  |
Transform /^table:name,age$/ do |table|
  table.hashes.map { |hash| hash[:name] }.map {|name| Person.find_by_name(name)}
end

You can also use Table#.map_column! and Table#.map_headers! to modify tables. See RDoc for details.

Last edited by Alohadeveloper, Mon Feb 01 03:24:23 -0800 2010
Home | Edit | New
Versions: