Cucumber step definitions with optional arguments

When I am writing cucumber step definitions that pass arguments, not all of those arguments are needed. And I don't want to write a separate step with or without those arguments. The best way to do this is with a non-capturing regex.

Take the following example (in Ruby):

Given /I am logged in as (.+)/ do |user|
  ...
end

What if I don't want to define a user in every scenario? A default user would be great when none are passed. Since the verbiage works without this portion: as (.+), I'm going to do non-capturing regex around it, which looks like the following:

Given /I am logged in(?: as (.+))?/ do |user|
  ...
end

There are 2 capture groups. The first captures the entire string and the second captures the argument I'm trying to pass. I add ?: which defines the first group as non-capturing. The second group remains the same. How I make it optional is by adding a ? (question mark) to the end of the first group.

Now I can hit two birds with one stone like so:

Given I am logged in
Given I am logged in as some_user

Both will match a single step definition. Don't repeat yourself.

May 15, 2015