Gherkin: a primer
Improve feature robustness through slim documentation
While working on a recent project, I discovered how useful Gherkin can be to clarify features and encourage behaviour-driven development. In short—Gherkin is a way to document changes on a system level—which is easy to interpret for non-developers—making it easier to close the gap between the business side and the tech side of any product team.
From a design point of view, writing Gherkin is comparable to user stories: both approaches outline intended behaviour. Gherkin however really shines during the implementation stage because its phrasing can be converted into reusable snippets for testing.
By adopting Gherkin, you actively contribute to the testing process because you write your own tests for the feature you're about to design. This lightens the load on the QA and engineering sides while preventing unforeseen bottlenecks. In this post, I'll only cover the syntax of Gherkin, but there are some great tutorials on how to convert Gherkin documentation into testing scripts for those interested.
So how does it work? Imagine working on a webshop and you’d like to create an ‘add to shopping cart’ feature. In its most basic form, you could write this feature out in Gherkin as follows:
Feature: Add to cart
When a customer adds an item to the cart
Then the item should be displayed in the shopping cart
- The when signifies an action or event
- The then describes the desired outcome
This example is pretty straightforward, so let's pretend the shopping cart is only showing up for logged in customers and we want to reconfirm the action back to the user once an item gets added to the cart. To avoid repetition and keep things readable, we can use a given
and an and
statement as below:
Feature: Add to cart
Given a customer is logged in
When a customer adds an item to the cart
Then the item should be displayed in the shopping cart
And a modal should reconfirm the item is added
Great, thus far we’ve described a single scenario for this feature—adding an item to the shopping cart. Features often translate into multiple scenarios and edge cases.
Let’s pretend your team is asking what would happen if a user would hit the add to cart button again? After some thought, you decide to show an extra warning once someone adds the same item twice to the shopping cart. Let’s translate this in a new scenario
for the feature:
Feature: Add to cart
Scenario: Customer adds item to cart
Given a customer is logged in
When a customer adds an item to the cart
Then the item should be displayed in the shopping cart
And a modal should reconfirm the item is added
Scenario: Customer adds same item twice
Given a customer is logged in
And an item is already in the cart
When the customer tries to add that same item again
Then a warning modal appears
And the customer should reconfirm their action to add the item
Keep adding new scenarios to a feature until you feel like all major edge cases are addressed. Congratulations, you now have a feature written out in a way anyone can interpret it. For a designer, this is a great place to be in:
- Having a shared understanding of how the feature works beyond the UI helps to spark discussions between team members and document newly made decisions. This will result in fewer ‘unfortunate surprises’ after the implementation is finished.
- Understanding the different scenarios early on helps to shape and scope the work to be done on the technical side, this is useful information to have for anyone on the business side too.
- You’ve just saved yourself a lot of time by holding off from designing out every interaction upfront (although you still can if you think it’s necessary).
- Well written Gherkin documentation is automatically checked against the system’s behaviour, leaving little room for misinterpretation.
I’m still figuring things out myself, but I’ve already noted some things that helped me improve my documentation:
Don’t get caught up in the details
Gherkin works best to explain the intended behaviour of a change, not the actual implementation. Focussing on the latter often results in lengthy documentation. In the example, it doesn’t matter whether we the team decides to implement a single button or a complex dragging interaction to add an item to the shopping cart—it ultimately wouldn’t change the documentation.
Consider using a background if your scenarios share the same givens
When writing scenarios within the same feature, it’s likely that you’ll reuse the same given. While the scenarios in the example were not very complex, they both used the same given (a customer is logged in). If we were to expand on the complexity of these givens or add more scenarios, it could be useful to add a separate background
statement instead. Backgrounds are also a great way to tackle a feature from different kinds of users. We could add two different actors to our example using a background as follows:
Feature: Add to cart
Background:
Given a logged-in customer named "Anne"
And an unregistered user called "Sam"
Scenario: Logged in user adds item to cart
When Anne adds an item to the cart
Then the item should be displayed in the shopping cart
And a modal should reconfirm the item is added
Scenario: Unregistered user adds item to cart
When Sam adds an item to the cart
Then Sam needs to complete the signup before the item gets added
Avoid using multiple ‘when’ statements in a scenario
As the Gherkin documentation suggests, if you feel compelled to add more when
statements in a scenario, it’s usually a sign that you could split the scenario up into smaller ones. I like to check whether I can convert my when
into a given
first. If that fails, I usually break it up into a new scenario.
All in all, I find Gherkin a pretty useful way to outline features and will continue to use it. It helped me and my team patch holes in upcoming features early on and scope the work more accurately. Feel free to give it a go yourself!