Step definition arguments
- C#
- JavaScript
- Go
The Cucumber Expression docs are quite helpful here. Take a moment to review them.
The Sean is at {int}, {int} and Lucy is at {int}, {int} Cucumber Expression are almost identical except for the person’s name. We’re already using {int} output parameters to extract the coordinates and pass them to the step definition.
Let’s replace the person’s name in the Cucumber Expression with another output parameter so that the person’s name is also passed to the step definition as an argument.
In the first of the existing step definitions, replace Lucy with {word} to make it an output parameter that matches a word:
{word} is at {int}, {int}
Now that the cucumber expression has 3 output parameters, the step definition method is going to need an equal number parameters.
What type should the new parameter be? What’s a good name for it?
Replace the hard-coded "Lucy" in the body of the step definition method with your new parameter.
Do not modify the feature file.
Run SpecFlow.
You should get a BindingException because of an ambiguous step definition.
- What do you think an ambiguous step definition is?
- What should you do to fix it?
Run SpecFlow and check everything is still working as before.
Cucumber Expression are new to SpecFlow and to be able to use it an additional NuGet package, CucumberExpressions.SpecFlow.3-7 has to be added to the project. Even if you have enabled Cucumber Expressions, you can still use Regular Expressions as well. In the exercise above, using (.*) instead of {int} and {word} provides the same result.
The Cucumber Expression docs are quite helpful here. Take a moment to review them.
The step definitions:
Given('Lucy is at {int}, {int}', function (x, y) {
shouty.setLocation('Lucy', new Coordinate(x, y))
})
Given('Sean is at {int}, {int}', function (x, y) {
shouty.setLocation('Sean', new Coordinate(x, y))
})
are almost identical except for the person’s name. We’re already using {int} output parameters to extract the coordinates and pass them into the step definition.
Let’s replace the person’s name in the Cucumber Expression with another output parameter so that the name is also passed into the step definition as an argument.
In the first of the existing step definitions, replace Lucy with {word} to make it an output parameter that matches a single word:
Given('{word} is at {int}, {int}', function (name, x, y) {
shouty.setLocation(name, new Coordinate(x, y))
})
Now that the Cucumber expression has three output parameters, the step definition function needs three parameters too (name, x, and y).
What’s a good name and type for the new name parameter? Where else in your step definitions can you now remove hard-coded names like "Lucy" and use the name argument instead?
Run SpecFlow.
You should see a “Multiple step definitions match” error, because the new generic step definition overlaps with the old Sean is at {int}, {int} step.
Why is Cucumber unhappy when more than one step definition matches the same step text? How can you resolve this? (Hint: remove or rename the now-redundant specific step definition.)
Run Cucumber again and check everything still works as before.
The following step definitions are almost identical except for the person’s name.
sc.Step(`^Lucy is at (\d+), (\d+)$`, lucyIsAt)
sc.Step(`^Sean is at (\d+), (\d+)$`, seanIsAt)
We’re already using the (\d+), (\d+) capture groups extract the coordinates and pass them to the step definition function as x, y int. Let’s replace the person’s name in the step definition with a regex capture group so that the person’s name is also passed to the step definition as an argument.
In the first of the existing step definition regular expressions, replace Lucy with (\w+) to make it a capture group that matches a word:
^(\w+) is at (\d+), (\d+)$
Now that the regular expression has 3 capture groups, the step definition function is going to need an equal number parameters.
What type should the new parameter be? What’s a good name for it?
Replace the hard-coded "Lucy" in the body of the step definition function with your new argument.
Do not modify the feature file.
What do you think should happen when you run SpecFlow?
Run SpecFlow and check your answer.