This is a very quick-and-dirty cheatsheet for descrbing features in Gherkin. Through this, we'll use the example of describing a user signing into an application.
The first thing to do when writing a story for a feature is to give the story a title and a synopsis. These are effectively free-form text with the exception that the title should start with "Feature: " and the synopsis should be indented one level:
Feature: User Signs In
The website requires authentication, so I want the users to be able to sign in.
A sceanrio is made up of a declaration and a list of steps that begin with words like Given
, When
, and Then
. The first scenario listed in the feature should be the "happy path" ... a description of what happens when everything goes correctly. Beyond this, there may be other success scenarios to describe for the feature, but there will probably also be a few failure cases to describe as well.
A scenario declaration is more or less just a title for the scenario in question, beginning with "Scenario: " and finishing with a free-form title. Our happy path declaration looks like this:
Scenario: User signs in successfully
As mentioned above, there are three main keywords for use in scenario steps: Given
, When
, and Then
. Respectively, these are used for setting up preconditions for the user's actions to be viable, stating the actual actions that the user performs, and listing the side-effects of the user's actions. As a rule, these should always be stated from the point of view of the user unless this is strictly impossible (and if it's strictly impossible, it might be worth figuring out if there's a better way to talk about the feature). You can also use the And
and But
keywords as a way to avoid writing the same keyword over and over again. These are replaced by the previous canonical keyword when the test is run.
Use Given
to set up the application state that must be in effect for the user to be able to do the actions described later in the scenario. For example, for a user to be able to sign in, they must have login credentials, so you might start the scenario off with something like this:
Given I am a user with valid credentials
And I'm on the user sign in page
Use When
to specify the actions that a user performs during the scenario. Using our example, the user might do the following:
When I fill in my username
And I fill in my password
And I click the "sign in" button
While the above definitely works, it's also a bit verbose, and it becomes tedious to both write and read scenearios that are written in such a style. To that end, it might be preferable to state this instead:
When I submit my username and password
The guideline here is to write stories the way that you'd want to read them. If you prefer a very high level of atomicity, text is cheap. If you prefer brevity, that works just as well (and usually better if I'm being honest).
Use Then
to specify side effects that should be true after a user performs their actions for the scenario. For example, after logging in, a user might be redirected to a dashboard of some sort:
Then I land on my dashboard
At this stage, the full feature description for users signing in looks like this:
Feature: User Signs In
The website requires authentication, so I want the users to be able to sign in.
Scenario: User signs in successfully
Given I am a user with valid credentials
And I'm on the user sign in page
When I submit my username and password
Then I land on my dashboard
That is short, sweet, and seems to describe the happy path well. At this point, we could consider this story fully-written, but we really should add some failure scenarios, and there's actually something else that we should talk about ...
There is another special optional section of a Feature
called Background
. A Background
looks exactly like a Scenario
, except that it lacks a title and generally only contains precondition (Given
) declarations. This is because a Background
is considered to be true for every scenario in a given feature. While our current feature description is well and good, for longer stories with many scenarios that require the same setup, this is an incredibly handy section to include. This is what our full example might look like with one:
Feature: User Signs In
The website requires authentication, so I want the users to be able to sign in.
Background:
Given I'm a user with valid credentials
Scenario: User signs in successfully
Given I'm on the user sign in page
When I submit my username and password
Then I land on my dashboard
As mentioned above, we've covered the "happy path" for our feature, but we should also consider if there are failure modes for the feature. For example, what if the user in our story gets confused as to which password they used for the site? That might look something like this:
Feature: User Signs In
The website requires authentication, so I want the users to be able to sign in.
Background:
Given I'm a user with valid credentials
And I'm on the user sign in page
Scenario: User signs in successfully
When I submit my username and password
Then I land on my dashboard
@failure
Scenario: User provides the wrong password
Given I've remembered my password incorrectly
When I submit my username and password
Then I see an error about my login credentials
And I land on the user sign in page
But I am not signed in
You might notice that I've added something above the failure scenario: @failure
. This is a tag, a bit of metadata that doesn't (by default) have any real meaning outside of our knowing that this is one of the failure scenarios for the feature. You don't have to add tags. They're just kinda nice as a comprehension aid.
- Aside from the keywords in play, try to use your own natural language flow. In the end, stories need to be easy to read and understand to ensure that everybody lands at the same end result.
- While it's perfectly acceptable to write very verbose step declarations and highly atomic step lists, it's usually better to be a little hand wavey. Sixteen steps to describe the mouse movements that the user makes to get their cursor over the "submit" button is very monotonous in comparison to
When I click the submit button
. And I wouldn't have such a grand example of what not to do if I hadn't actually run into it :) - Don't stress over your stories too much. These should almost be fun to write, and if they start being a drag, you might be overthinking it a bit. Take a break, perhaps even just send what you have and be ready to talk about the story with your other stakeholders. In a perfect world, we'd all be sitting in a room (or at least a Skype call or something) and writing these in real-time, but that's often not feasible with disparate schedules. That being the case, stories written in isolation are most typically considered first drafts, so they're not really worth losing sleep over.