Don't Repeat Names in Cucumber Scenarios

Update 06/12/2014: I created a gem for this and other things, read an introduction here

When the same name is repeated all over the place in a cucumber scenario, it can be difficult to read.

1
2
3
4
Scenario: Withdrawing some cash
  Given a deposit account with 1000
  When I withdraw 100€ from the deposit account
  Then there should be 900€ on the deposit account

It would be better if we could write it like that

1
2
3
4
Scenario: Withdrawing some cash
  Given a deposit account with 1000
  When I withdraw 100€ from the account
  Then there should be 900€ on the account

Sometimes we actually want to repeat the names though, either for clarity, or if we are dealing with many accounts within the same scenario.

To make both my scenarios more readable and my steps more versatile, I created special main_account_name accessors and a custom transform.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def main_account_name
  @main_account_name ||= "credit"
end
def main_account_name=(account_name)
  @main_account_name ||= account_name
end

CAPTURE_ACCOUNT_NAME = Tranform(/^(a|an|the) *(.*) account$/) do |_prefix, account_name|
  if account_name == ""
    main_account_name
  else
    account_name
  end
end

When creating the account, I added some code to set the main_account_name

1
2
3
4
Given(/^(#{CAPTURE_ACCOUNT_NAME}) with (\d+)€$/) do |account_name, amount|
  ...
  self.main_account_name= account_name
end

It is then possible to write steps like

1
2
3
When(/^I withdraw (\d+)€ from (#{CAPTURE_ACCOUNT_NAME})$/) do |amount, account_name|
  ...
end

that will match both “the deposit account” and “the account” depending on context.

It would be really nice to be able to write things like

1
  Then there should be 900€ on it

but because of the way cucumber handles transforms, the only way I know to do that is to write a new step definition.

Comments