Skip to content

Instantly share code, notes, and snippets.

@ess
Last active December 4, 2019 12:06
Show Gist options
  • Save ess/71426e8175f0c80c4c4b27af4c3d109d to your computer and use it in GitHub Desktop.
Save ess/71426e8175f0c80c4c4b27af4c3d109d to your computer and use it in GitHub Desktop.

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.

Basics

Starting A Story

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.

Writing Scenarios

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.

Declaration

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

Steps

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.

Preconditions

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

Actions

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).

Side Effects

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

Full Example

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 ...

Background

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

Failure Scenarios

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.

Tips

  • 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment