Cucumber: Skipping steps in a scenario outline, based on the current example

In Cucumber, scenario outlines help avoiding tests that are basically the same, except for a few variables (such as different inputs). So far, nothing new.

The problem

Now what if your test should (or should not) do something, like filling in a field only for some tests?

    Scenario Outline: ...
      When I open the form
        And I fill in "Name" with "<name>" # <= we want to do this only occasionally
      Then everybody should be happy
      
    Examples:
      | name  |
      | Alice |
      | Bob   |

You could of course have a step that says something like "When I do not fill in "Name" with "..."" -- but that implies there actually is a "Name" field. \
If there is none, your test gives a false impression of what should happen which is not a good idea.

A solution

You could move your entire step into the examples, but that would be quite cumbersome.

Instead, you may want to write your test like this:

    Scenario Outline: ...
      When I open the form
        And I <maybe do> this: I fill in "Name" with "<name>"
      Then everybody should be happy
      
    Examples:
      | name  | maybe do  |
      | Alice | do not do |
      | Bob   | do        |

Define the "do this" step as follows.

    When /^I (do|do not do) this: (.*?)$/ do |do_or_do_not, step_text|
      step(step_text) if do_or_do_not == 'do'
    end

A word of advice

Note that this does not necessarily increase your test's readability. If you have a very long test, you obviously do not want to duplicate it and your tests might very well benefit from this approach. Use it with care, however -- doing this more than a few times in your scenario will do more harm than good.

As always, you need to find the sweet spot between duplication and over-engineering (and thus making the test impossible to read).

An alternative is also to hide that functionality behind other steps that do more complex things differently.

Arne Hartherz