Transcripted Summary

In the previous chapter, we saw how to turn our specifications, written in Gherkin, to executable code using SpecFlow.

In this chapter, we are going to make our Step Definitions more versatile by looking at step parameterization and by using the power of regular expressions to our advantage.

As you convert your examples gathered in the Discovery phase to Gherkin, you might notice that a lot of the steps in your specifications are very similar, and the only thing that varies is the value you send as input to the system you're describing, or observe as output from that system.

As an example, consider the steps when they apply for a $999 loan and when they apply for a $1 loan described in the first Scenario Outline in our specifications here.

Scenario Outline: Loan amounts under 1000 are always approved
	Given John is an active ParaBank customer
	When they apply for a <amount> dollar loan
	Then the loan application is approved
	| amount |
	| 999    |
	| 1      |

It would be very inefficient to create 2 separate Step Definitions for these steps when the only thing that changes is the loan amount, which is a value we likely want to use as input in the acceptance tests for our loan application implementation anyway.

For example, to fill that value into a form on the UI or to send it as a request body value in an API call. Chances are high that the implementation for both these steps would be exactly the same, no matter the value of the loan amount.

This would lead to a lot of duplication in our test code.

This is exactly the reason why SpecFlow, just like pretty much every other tool that supports BDD and Gherkin, allows you to create parameterized steps instead.

If you look at the StepDefinitions that have been created, SpecFlow has even identified a potential opportunity for parameterization already by turning the loan amount into a parameter all by itself.

We might want to change the name from “p0” to “loanAmount”, though, to make our code a little more clear.

Once we start implementing the StepDefinitions methods, we can refer to the value written in the step using the corresponding argument that is passed to the StepDefinitions method.

When the Scenario that contains this parameterized step is run, SpecFlow will extract the parameter value from the step and pass it to the body of the StepDefinitions method so that it can be used in the acceptance test, either as an input value or an expected output value.

Especially with Scenario Outlines, where the same Scenario is repeated multiple times for different examples, you'll probably make good use of parameterized steps, you will probably make good use of parameterized steps.

As you can see, SpecFlow uses regular expressions to capture the variable parts of the step description in what is called a capture group, the part between brackets here.

There is a problem here, though.

The (.*) regular expression you see here matches pretty much everything, as dot [.] means every character and star [asterisk] means repeated 0 or more times.

Since we are working with a number in this step, we probably want to be a little more restrictive in the values we accept in our steps.

This is where regular expressions come in very useful.

When we replace the (.*) with (\d+) in our capture group, we have a step and Step Definition that only accepts integer values, as the “d” is short for digit, meaning characters between 0 and 9 inclusive, and the “+” means repeated 1 or more times — meaning that the loan amount value also cannot be left empty in our step anymore.

        [When(@"they apply for a (\d+) dollar loan")]
        public void WhenTheyApplyForADollarLoan(int loanAmount)

There's also an alternative to using regular expressions, and that is using what are known as Cucumber Expressions.

These allow you to use parameters in your steps and Step Definitions using more readable expressions, like this.

For many people, and in many cases, this will be easier to read and to write than regular expressions, but by all means, pick whatever works best for you.

It is good to note, by the way, that support for these Cucumber Expressions is native in SpecFlow from version 4 onwards.


If you're using an older version of SpecFlow, as I am in this video, you will need to add the CucumberExpressions.SpecFlow package corresponding to your SpecFlow version to your project, or else SpecFlow will not be able to parse your Cucumber Expressions.

Another place where we can benefit from the power of parameterization and regular expressions in our StepDefinitions is with the expected result of the loan application.

In our system, that result will be either approved or it will be denied.

And it's likely that these 2 StepDefinitions will contain the same code. Observe the actual loan application result and compare it with the predefined expected result, again “approved” or “denied.”

So why not limit the options to the possible values that can be produced by the loan processor?

We can do this easily using this regular expression.

This expression only matches the exact values listed in the expression, and nothing else, so this will match “approved” as well as “denied”, but no other value.

For example, when we use “processing” as an expected result, SpecFlow tells us there's no matching Step Definition.

By the way, I wouldn't use this technique once you've got more than, say, 5 possible values in your list because that will probably make your code harder to read and understand.

In those cases, you might want to use some other way of verifying that the value used is a valid one. For example, by accepting any string or integer value and dealing with the validation in your Step Definition implementation code.

After we have added this regular expression, the capture group, and the method parameter, we can remove the second Step Definition, resulting in less code for our StepDefinitions.

        [Then(@"the loan application is (approved|denied)")]
        public void ThenTheLoanApplicationIsApprovedOrDenied(string expectedResult)

This is another example of the power of regular expressions in our steps and Step Definitions.

The good news is that you can use a regular expression in one Step Definition and a Cucumber Expression in another without problems in SpecFlow, so you can decide what works best for you for each Step Definition.

There are many more examples of both regular expressions and Cucumber expressions that can be given. Especially with regular expressions, the opportunities are endless.

At the end of the day, though, it is all about making your steps and Step Definitions more flexible and removing unnecessary duplication in your Step Definition code.

In the next chapter, we are going to take a look at a different technique you can use to make your steps and Step Definitions more flexible. And that's by using table arguments in your steps and processing them effectively in your Step Definitions using a very useful but not very often mentioned SpecFlow utility class.


© 2024 Applitools. All rights reserved. Terms and Conditions Privacy Policy GDPR