Gherkin for designers

Gherkin is a powerful tool for describing system behaviours. By annotating your design deliverables with Gherkin, you will win the hearts of product, development, and documentation teams.

Francis Wu
UX Collective

--

Gherkins on a table.
Photo by Jonathan Pielmayer on Unsplash

In 2015, I was working in a small startup where I was acting as a product owner, UX designer, and front-of-the-front-end developer. Given my particular set of skills, I was able to implement my designs directly in code while skipping mockups. The upside was that design implementation happened blazingly fast. The downside was that my code would cause automated tests to fail.

That’s when my amazing development team introduced me to BDD (behaviour-driven development) and taught me how to debug and fix failing tests. And that’s where Gherkin comes in.

What is Gherkin?

Gherkin is a language used by software developers to describe expected system behaviours for automated testing tools. Gherkin’s plain-English syntax makes it very accessible. Because it can be written and understood by almost anyone, it can be a language shared by developers, technical writers, business analysts, product managers, and even designers.

How do you Gherkin?

Gherkin uses specific keywords to provide meaning to automated tests. Lines in a Gherkin document begin with specific keywords. Here’s a simple example:

Feature: LoginBackground:
Given the user is on the "login" page
Example: The user successfully logs in to the "home" page
When the user fills out the "login" form
And the user submits the "login" form
And the submission is valid
Then the user should be on the "home" page
Example: The user fails to log in
When the user fills out the "login" form
And the user submits the "login" form
And the submission is invalid
Then the user should be on the "login" page
And the user should see an "error" alert

Pretty straightforward, right?

The keywords I’ve used most frequently are Feature, Example, Given, When, And, and Background. Cucumber’s Gherkin reference has a few more keywords, but these have always served me well enough.

The Feature keyword provides a high-level description of your app’s feature, and typically groups related examples.

The Example keyword describes a feature scenario in a list of steps. The steps follow this pattern:

  • Given steps describe initial context (the past)
  • When steps describe an event (the present)
  • Then steps describe the expected outcome (the future)

Each step starts with Given, When, Then, or And. The And keyword keeps your Gherkin legible when you have successive Given’s, When’s, or Then’s. So instead of writing:

Example: Successive Whens and Thens
When the user fills out the "login" form
When the user submit the "login" form
When the submission is invalid
Then the user should be on the "login" page
Then the user should see an "error" alert

You could write something easier to read:

Example: Multiple Whens and Thens
When the user fills out the "login" form
And the user submits the "login" form
And the submission is invalid
Then the user should be on the "login" page
And the user should see an "error" alert

Lastly, use the Background keyword to avoid repeating the same Given steps across examples. Instead of writing:

Feature: LoginExample: The user successfully logs in to the "home" page
Given the user is on the "login" page
When the user fills out the "login" form
And the user submits the "login" form
And the submission is valid
Then the user should be on the "home" page
Example: The user fails to log in
Given the user is on the "login" page
When the user fills out the "login" form
And the user submits the "login" form
And the submission is invalid
Then the user should be on the "login" page
And the user should see an error message

You can keep things DRY with:

Feature: LoginBackground:
Given the user is on the "login" page
Example: The user successfully logs in to the "home" page
When the user fills out the "login" form
And the user submits the "login" form
And the submission is valid
Then the user should be on the "home" page
Example: The user fails to log in
When the user fills out the "login" form
And the user submit the "login" form
And the submission is invalid
Then the user should be on the "login" page
And the user should see an error message

With this example in mind, annotating your designs with Gherkin might look like this:

Designs for a “login” feature annotated with Gherkin.
Designs for a “login” feature annotated with Gherkin.

Gherkin writing tips

As you can see, Gherkin can be pretty easy to pick up. But if you work closely with BDD developers, you’ll find yourself in an endless but rewarding journey towards Gherkin refinery and mastery. Here are a few tips to facilitate that journey.

Tell your user’s story in the third person

For the sake of narrative consistency, it’s best to write Gherkin in either first or third person and not mix the two.

But between both choices, writing in the third person is more efficient and effective. This is because when it comes to user roles, writing in the third person is more expressive.

Consider the following first person example:

Given I'm an administrator
When I'm on a "user" details page
Then I should see a "delete" button in the app bar

Now consider the following third person example:

When the administrator is on a "user" details page
Then the administrator should see a "delete" button in the app bar

Both examples do the same thing, but the third person narrative is shorter and clearer.

Split for abstraction

Split your examples into identifiable behaviours that can be reused in the construction of other system behaviours. Here’s an example that can be split:

Example: The user successfully adds a cat
Given the user is on the "cats" collection page
When the user clicks on the "add cat" FAB
And the user is on the "add cat" page
And the user fills out the "add cat" form
And the user submits the "add cat" form
And the form is valid
Then the user should be on the "cats" collection page
And the user should see a "cat added" toast
And the user should see the new "cat" on the "cats" collection page

This might seem fine at a glance, albeit wordy. But if you consider an “unsuccessful” example, you’ll find yourself repeating the portion related to accessing the “add cat” page. By extracting this portion into its own example, it becomes reusable, like this (in bold):

Example: The user accesses the "add cats" page
Given the user is on the "cats" collection page
When the user clicks on the "add cat" FAB
Then the user should be on the "add cat" page
Example: The user successfully adds a cat
Given the user is on the "add cat" page
When the user fills out the "add cat" form
And the user submits the "add cat" form
And the submission is valid
Then the user should be on the "cats" collection page
And the user should see a "cat added" toast
And the user should see the new "cat" on the "cats" collection page
Example: The user fails to add a cat
Given the user is on the "add cat" page
When the user fills out the "add cat" form
And the user submits the "add cat" form
And the submission is invalid
Then the user should be on the "add cats" page
And the user should see an "error" alert
And the user should see erroneous fields marked as such

Applying this to your designs might look like this:

This level of abstraction keeps things DRY and also permits your design documentation to scale. Imagine extending the “add cats” page with an import function:

Example: The user accesses the "import cats" page
Given the user is on the "add cat" page
And the user clicks on the "import" button
Then the user should be on the "import cats" page

Pro tips:

  • Fight the urge to ruthlessly abstract all the things. Clarity is equally important!
  • If you find yourself using more than one set of When’s and Then’s, that’s usually an indication the example should be split.

The magic of Gherkin

Gherkin’s power lies in its accessibility for both humans and computers. I think it should be part of every UX designer’s toolkit.

Connectors optional

Connectors are great for conveying user flows in mockups. Unfortunately, Figma doesn’t have native support for connectors. And if the idea of using 3rd party arrow or connector plugins makes you uncomfortable, Gherkin can still effectively communicate user flows. Your mockups also feel less cluttered, which is a nice bonus.

A shared language

Not only is Gherkin great for describing system behaviours, but it also trains you to be mindful about consistency. As you write more Gherkin, a writing style will emerge organically over time, especially if supported with OOUX.

Strategic positioning

Given its accessibility, Gherkin-annotated artificats can be very impactful across your organization’s departments.

For the product team, it gives them confidence in your designs. For the sales team, it gives them an accurate vision of the future they can sell. For the documentation team, Gherkin already reads like user documentation. And for development teams, Gherkin gives them a head start, whether they practice BDD or have a more traditional QA process in place.

This kind of reach can make you indispensable. Perhaps even a linchpin.

Expedite onboarding

I’ve seen new developers read BDD tests as part of their onboarding. Seeing them spend a day reading only to emerge with a fair understanding of how their apps are expected to work was not unlike seeing Neo wake up knowing kung fu.

Similarly, sufficiently well organized and annotated Figma files could hypothetically deliver a similar outcome for a UX team. I say “hypothetically” because I’ve yet to test this. If you beat me to it, be sure to share your experience!

Mockups optional

As a designer, one of the most remarkable outcomes of learning Gherkin is the time it saves. When simple feature enhancements could be described in words, mockups become optional. Not only will your Gherkin reflect domain objects and rules, but your usage of component names will also become deliberate.

Consider the following example, where a user successfully adds a cat.


When the user fills out the "add cat" form
And the user submits the "add cat" form
And the submission is valid
Then the user should be on the "cats" collection page
And the user should see the new "cat" on the "cats" collection page

If we wanted to enhance this experience with a toast, the Gherkin might look like this:


When the user fills out the "add cat" form
And the user submits the "add cat" form
And the submission is valid
Then the user should be on the "cats" collection page
And the user should see a "Good job, you have a new cat!" toast
And the user should see the new "cat" on the "cats" collection page

With a mature design system and product trio in place, the implementation of this design is on rails. Developers can see what component and copy to use, and the design system dictates how the component behaves.

If you review the Gherkin I’ve provided in this post, you’ll also notice the consistent use of:

  • form
  • page
  • collection page
  • details page
  • alert

Sure, some simple feature enhancements can also be supported with napkin doodles, wireframes, or even high fidelity mockups. But when mockups are optional, that gives you more time to spend on truly complex features where mockups are necessary.

Special thanks

Gherkin has served me well as a product owner, UX designer, and front-of-the-front-end developer. I probably would have never encountered this had it not been for Gary Haran, Sophie Déziel, and Rachel Carvalho. Now I introduce Gherkin to every team I join.

--

--

9 parts dad. 7 parts designer. 5 parts developer. 3 parts product manager. Some parts private.