Gherkin is a domain-specific language used in Behaviour Driven Development to describe the business behaviour that should be modeled by the software being developed.
There are many good reasons to use Gherkin. Possibly the three most important are:
Gherkin provides a framework we can use to define what the end-user should expect from the features we’re developing, written in a way that everyone in the team can understand. These expectations should be defined clearly with detailed examples that leave no ambiguity regarding the acceptance criteria required by the business user to validate the end product.
## Format Basics
Gherkin is a plain text language that uses keywords, indentation and formatting to describe software specifications in terms of features, scenarios and steps.
Definitions for these components are written in a .feature file. Each .feature file should contain just one feature definition, followed by one or more scenarios. Each scenario has a number of steps explained using a Given-When-Then structure.
A feature file begins with the title of the feature introduced by the keyword “Feature:” followed by a short description of what the feature should do. Note that this text is usually not processed by any tools downstream and is generally used to convey information to the business users, developers and testers.
It’s important to understand that the description following the title should focus on the value of the feature to the business and the benefits it will deliver to the business end-users. It should not include any information about the implementation of lower-level functionality. Think of it as answering the questions “Who is this for?” and “Why should they want it?”
The aim is to have just one feature defined per .feature file, so you’ll end up with many small files rather than a few large ones. This way it will be easier to process and organise these files downstream as features are implemented.
Next in the .feature file comes the scenario definition. Each feature may have many scenarios. The title is demarcated by the keyword “Scenario:”. You have the option of writing a short description of the scenario after the title and before the first “Given:” statement. This description is sometimes called the ‘scenario brief’.
Scenarios should capture the users’ interaction with the system and the expectations they should have for the feature. However, to explain a feature fully usually requires many scenarios in order to account for all the possible permutations of use cases.
The details of the scenario’s starting point, actions and completion point are defined in the form of ‘steps’.
Each scenario is made up of a number of steps. The starting point is indicated by the keyword “Given:”, the actions that are completed are indicated by “When:”, and the keyword “Then:” introduces the expected outcome or completion point. This Given-When-Then construct is the backbone of the Gherkin language.
The ‘Given’ statement sets the context for the scenario – the known state that needs to be set up before the scenario is executed.
It’s important to get the starting point correct because the automated tests being driven from the .feature files depend on the system under test being in the correct state before the test steps are executed. As any automation engineer knows, a system in an unknown state to start with will lead to unreliable and unexpected tests results.
The purpose of the Given step is to define the known state in enough detail for the automated tests to run reliably. No assumptions should be made and no Given statements should be left out.
The ‘When’ steps define the actions performed by the feature and the events that take place as a result. In the automated testing domain, the When steps are the test steps that need to be executed. These will be interpreted by the test automation tool to be run as test actions to simulate the end user’s interactions with the software.
The ‘Then’ steps define the expected state of the system after the ‘When’ steps have been completed. In our case, they are the expected test results. These statements should describe the conditions that the user would see. Because we’re following BDD principles, acceptance criteria should be expressed from the perspective of the business or end-user.
Given-When-Then statements have their limits. If you need to expand on these, you can include additional logic using the “And:” and “But:” keywords. These statements are optional, but can make your scenarios more readable.
You can further increase readability by using indentation to emphasise blocks of related steps, similar to the way you might indent code in a scripting language like Python. Use space characters rather than tab to facilitate portability.
You may find that you end up with lots of similar steps. For example, you may have lots of Given statements that only differ by some data value. This becomes very repetitive to duplicate and maintain. To avoid this, we use multiline steps. Multiline steps allow us to create tables where one row represents a single “Given:” statement. This removes a lot of the repetitive statements and clauses, replacing them with one neat data set used to define the starting condition.
You can also use tables to define permutations of a scenario in a scenario outline. Each row in the table is run for the same scenario. In this setup, you use placeholders (similar to variables) that are interpreted and replaced at run time with the values from the fields in the table. Placeholders are defined using the `<` and `>` characters.
The “Background:” keyword allows you to add setup statements for *all* scenarios in a .feature file. The Background block will be run before *every* scenario block. If you have setup steps that are common to every scenario, using the Background keyword will greatly simplify your life.
For complex (and even some not-so-complex) projects the number of .feature files and scenarios can quickly become overwhelming, making it difficult to organise and keep track of scenarios. Identifying scenarios of a particular type among many .feature files can become almost impossible. To solve this, Gherkin has a “Tag:” keyword that allows you to add identifying tags to features and scenarios.
If you set your tags up intelligently, you can use them to run a subset of your automated tests for a particular group of features or for a set of scenarios that cover a specific area of functionality.
One of our main reasons for using Gherkin is to facilitate automated testing. The .feature files containing the application use case scenarios can be used as inputs to your automated testing system. A scenario can be turned into a test that will be used to verify the delivered feature against its acceptance criteria.
If the acceptance test fails, then either the acceptance criteria are incorrect and need updating, or the software does not correctly deliver the outcomes required of it. By implementing these acceptance tests as automated tests we can increase the speed of the feedback loop and provide the capability to run the tests frequently and on-demand.
Ultimately, we end up having the specifications defined upfront and being validated at the end by the automated tests. The test execution results are then fed back to the start of this iterative process and, in the case of test fail, the .feature files are further clarified or the software under test is updated until it meets the acceptance criteria.
Therefore, it is vital that the .feature files are updated and referenced regularly because they are linked inextricably to the tests that everyone is monitoring to see if the software is ready for release.
In traditional development processes and models, the documents tend to get written once and never updated thereafter. With BDD, because the documentation drives the tests, and the test results dictate the release readiness the software, the documentation has to be kept up to date if the software is ever going to receive a pass status from the automated tests. For this reason, the .feature files created as part of the BDD process are often referred to as ‘living documentation’, because they live alongside the software and its tests, and all three elements are updated together.