In order for Given-When-Then scenarios to facilitate good discussions, variables must be easy to spot. Unless people can tell easily if some phrase or word might change, they will not be able to ask good questions. In this article, I’ll show you four easy ways to make parameters more prominent.
Let’s start with a quick exercise. Look at the following scenario:
Given an open account with 100 USD balance When the account receives a 20 USD payment Then the account balance will be 120 USD
Take a moment to list the potential parameters for this example. Find all the values that might change in other examples for the same scenario. Don’t read the next paragraph until you’ve written them down.
Most people will note the numbers: the starting balance and the amount of the payment. Some will also list the currency. An account may receive a payment in a different currency, and this can trigger more complex rules around foreign exchange (for example, my bank will process same-currency payments even after working hours, but only settles forex payments during working hours).
How about the word “open”? If you had that in your parameter list, you’re one of the very few readers that pay close attention. It’s not obvious at first glance, but this parameter is quite important to identify for collaborative analysis. Spotting this variable helps us uncover important questions, such as “Should this feature deal with other account states?” For example, what happens if a payment comes for a frozen account? Without more context, it’s impossible to know if this is in scope or not. That’s why making parameters more prominent is so important.
One easy way to make parameters visible is to turn a scenario into an outline, and replace parameters with placeholders. If the account status is important, the scenario outline could look similar to this:
Given a <status> account with <old balance> balance When the account receives an <amount> payment Then the account balance will be <new balance> Examples: | status | old balance | amount | new balance | | open | 100 USD | 20 USD | 120 USD |
This is a simple and popular method of highlighting variables, but it’s a bit too complicated if there’s only a single example. It’s also not ideal for scenarios with a lot of parameters. The example table can become wide, and sprinkling placeholders all over the scenario outline can make it quite repetitive. Consider what happens if we split out currencies:
Given a <status> account with <old balance> <account currency> balance When the account receives a payment of <amount> <payment currency> Then the account balance will be <new balance> <account currency> Examples: | status | old balance | account currency | amount | new balance | | open | 100 | USD | 20 | 120 |
This is already getting a bit difficult to process. It will become even worse if we add a few more steps with foreign exchange rates and working hours. Outlines with more than 4-5 parameters tend to be almost unreadable, so people glance over them instead of reading the details.
An alternative approach that works well for more complex scenarios is to just mark parameters with some special delimiters. By convention, people often use quotes. This makes test automation easier, but it also makes parameters easy to spot. Here’s an example:
Given an "open" account with "100 USD" balance When the account receives a payment of "20 USD" Then the account balance will be "120 USD"
Readers of the previous scenario will easily notice that the word “open” has quotes around it, and this is often enough to signal that it’s not just scenario choreography.
Quotes are great for simple parameters, but they are not good for complex values. Putting “20 USD” in a single quote clause can obscure the fact that currencies can vary, but putting quotes around those two values separately (
the account receives a payment of "20" "USD") just looks silly and confusing.
Another way of making parameters easy to spot is to make sure that the parameter value is always at the end of the line. It’s useful to have some kind of subtle hint that a line contains a variable. I tend to use colons (:) for this purpose. For example, the previous scenario could look like this:
Given an account with status: open And with account balance: 100 USD When the account receives a payment of: 20 USD Then the account balance will be: 120 USD
It’s often best to have just a single parameter per line. We could perhaps restructure the scenario to point out the currency better:
Given an account in currency: USD And the account status is: open And the account balance is: 100 When the account receives a payment in: USD And the payment amount is: 20 Then the account balance will be: 120
Using colons to signal a variable is great if most parameters are independent. In this case, four values relate to an account and two relate to a payment. As a result, the words “account” and “payment” need to be repeated many times, which is making the scenario wordy.
With complex variables, parameter tables might be a better solution. Tables can reduce redundant wording and point out parameter structure clearly.
One way to use tables for complex values is to list individual parameters in rows, using the first column for the property name, and the second for the value. Here is how that could look:
Given an account: | currency | USD | | status | open | | balance | 100 | When the account receives a payment: | currency | USD | | amount | 20 | Then the account balance will be: 120
Another way of using tables is to structure individual properties in columns, and use a single row for the values. You can use a header row for property names, or omit it for simple structures where the names can be implied. For example, in the following scenario the first table has a header, and the second does not. It’s pretty obvious that 100 is an amount and USD is a currency when listing a payment, so we can simplify the scenario by omitting that header.
Given an account: | currency | status | balance | | USD | open | 100 | When the account receives a payment: | 20 | USD | Then the account balance will be: 120
I like using the first approach (values in rows) when a parameter has more than 4-5 properties. I like using the second approach (values in columns) for simple structures, especially when the property names can be implied.
Notice the colons at the end of the lines preceding each parameter table. This is not mandatory, but it’s a useful convention. A colon at the end of the line hints that the scenario step is not finished. A person reading it will know to consider the next few lines also as part of the current step. For SpecFlow users in particular, ending lines before a table with a colon also helps with editing and auto-completion.
All these approaches have advantages and limitations, so experiment a bit to decide which one to use in which case. Irrelevant of which approach you choose, remember that somehow making parameters stand out from the rest of the text is critical for enabling readers to ask good questions.
Do you have a different solution for this problem? Please let us know and we’ll publish it in one of the following articles. You can do so using a quick form on this link.
Finally, here’s a quick reminder that you still have almost a week to participate in the current Given-When-Then With Style challenge: How to specify relative periods. Cast your votes until Monday 23rd November and check back next week for the results.
PS: … and don’t forget to share the challenge with your friends and team members by clicking on one of the social icons below 👇