The “Given, When, Then” format was originally developed by Dan North and Chris Matts, way back in 2004. It was originally intended as a way of describing class behaviour using something that didn’t involve testing. It was a way of having useful conversations about code. It turned into a way of having conversations about entire systems, with examples of how those systems behave. It was always meant to be readable by people who didn’t code (Chris Matts being a business analyst at the time) but it was never quite how people actually spoke.
In this post I want to look at ways of turning real conversations into Gherkin, while maintaining as much of the language as possible. If you’ve got any hints and tips of your own, please add them in the comments!
Get examples by asking for them
The best way to get examples is to ask someone, “Can you give me an example?”
Frequently, the people who are thinking of requirements are trying to think of all of them at once, so you’ll probably get something back that’s acceptance criteria rather than a concrete example.
For instance, if I ask:
“Can you give me an example of something that Word does?”
I might get back:
“Yeah, when I select text and make it italic it should be in italics.”
So I make it more specific.
“Can you give me an example of something you might want to make italic?”
“Sure. Let’s say I’ve lost my dog, and I’m making a poster; I want to make ‘Answers to Spot'” appear in italics.”
Usually when people come up with specific examples they’ll come up with something that’s a bit surprising or funny; something which gives you insight into why it might be valuable as well as what you can do with it, without going into how. Listen to what people actually say!
While you’re practicing capturing real scenarios in real conversations, start by writing down exactly what people say. You might come up with something like the above. Or perhaps they’ll say something like:
If I bought the microwave on discount then I bring it back for a refund, I should only get $90 instead of $100.
The closer your scenarios match the real language people use, the more readable and interesting they’re likely to be.
Draw out the Givens, Whens and Thens; don’t force them.
People don’t use “Given, When, Then” in conversation. I frequently find that:
- people use “if” where Gherkin uses “given”
- or they use “Let’s say this happened…”
- or say “well, if I’ve already done X…”
- people use “then” instead of “when”, when they’re talking about an event they’re performing
- people often skip “then” altogether when they’re talking about an outcome, and occasionally skip “when”.
So you might get scenarios of the format:
- Let’s say <context>. I do <event>, then <outcome>.
- If <context>, then <event>, <outcome>.
- If we start on <context page>, then <event>, <outcome>.
It’s all pixies.
I do a lot of work with teams that have already done significant analysis before they even get a sniff at code. For those teams, the solution is already designed; but it’s still useful to help them talk about their problem without reference to the solution.
I tell them, “It’s not a <context page>. It’s a pixie. You’re talking to a pixie, and your pixie is saying, ‘Okay, so what have you already said to me?'” And I make a very silly, high-pitched voice, which makes people laugh but also draws them away from the code and into genuine conversation.
“I’ve said that <context…>”
That’s better than “Given we start on <context page>”, because it doesn’t reference the fact that we’re using a web application, so you can always make a nice little app to do it instead. The UI is flexible, which is good, because people keep wanting to change it, especially when things are uncertain.
Or you could let the pixies do it for you.
Success vs. failure
Often people phrase steps exactly the same way, whether they’re successful or not. So you’ll get:
I submit <my application> and <look for this successful outcome>
I submit <my application> but miss out <mandatory field>
I often see this:
Given I have submitted my application successfully
When I enter my details successfully
I find it more readable to make the default event successful, and use try for unsuccessful events, so:
Given I’ve submitted my application
means you succeeded, while
Given I tried to submit my application
But it was audited and rejected
naturally flows; you recognise in the first step that there’s some other information that’s a bit different to normal. You can use this for events as well as contexts.
Use the word it, or he, she, etc. Nobody says:
Given John filled in his application
And the application meets the auditor’s regulatory requirements
When John submits the applicaton for approval
Then John should receive an email that his application has been approved…
Closer to the conversation would be:
Given John filled in his application
And it meets the auditor’s regulatory requirements
When he submits it for approval
You get the idea.
It’s OK to ignore bits in code.
If you want to make sure you can handle it, he, she or even an occasional John or the application without writing fifteen step definitions, you can turn them into arguments to the steps and then just ignore them. Call them actor_ignored or something similar so you know you won’t be using them.
It’s also OK to have steps which lend some understanding of why things are important, even though you’ve got no way of actually coding them. For instance:
Given I lost my dog
can just be an empty step. We don’t want to actually lose someone’s dog. Especially not to the pixies.