I've been working as a developer for some time and it happened a way, I've never used Gherkin before the winter of 2022. In this post, I will try to tell you why using Gherkin can boost your understanding of the product, improve its quality, and why you should at least know what it is.
Let's start with the definition. Gherkin is a language for describing features with human-friendly syntax. In a more formal way we can define it the following way:
Gherkin is a line-oriented language that uses indentation to define the structure(similar to YAML or Python)
Each line starts with a keyword that defines the following block or text which can be the definition of a feature, scenario, or description of the step. Let's consider a small example:
Feature: Door functionality
# The first scenario is describing success case
Scenario: Open the door
Given the user is staying in front of the door
When the user turns a door handle
And pulled the door
Then the door is opened
Using it is pretty simple. "Feature" is describing feature block, that contains several Scenario blocks and every scenario has steps, that describe user behavior with "Given, When, Then" schema.
- "Given" should contain the initial situation description or actions we need to perform to make possible to make "When" step. It can be launching the app, opening the page or modal. In the example above user should stay in front of the door to start opening it.
- "When" contains action or actions that should be performed to get some result or change the application state. User make two actions in the example - turning the handle and pull the door to make it work.
- "Then" describes the result or state that user sees after performing previous steps. It is opened door in the example above, but it might be some result, let’s say 42.
- "And", "But" these two steps can be added to any of the step above or to all of them to enrich step with more details
- There are some other keywords in Gherkin, that can simplify scenarios, but I don’t use it for now, because they are needed for simplification of the tests scenarios and not that necessary if you’re just writing story description
More about Gherkin you can read in cucumber documentation
The main benefit of using Gherkin is the possibility of communication between technical specialists and product people with the same language. It seems like a small thing, but in reality, it has a significant impact on the development process. It’s not a coincidence that the picture below causes nervous laughter from anyone who has even been involved in software development.
Standardizing of task's descriptions allows you to improve its quality and avoid bad descriptions, like this one “We've discussed it on Skype” or vice versa several pages with vague descriptions of the desired functionality. With standards, developers are not needed to delve into heterogeneous task descriptions to understand exactly what kind of behavior they need to add to the system. They will just know what to expect. At the same time, the product owner will easily describe the desired behavior in the form of a set of steps, he/she is doing it all the time anyway, just in a different manner.
Of course, Gherkin will not insure you from mistakes in the task’s descriptions, but with proper usage and involving the whole team in supporting it, improvement will be really significant. Scenarios might be easily verified by any member of the team during the grooming(refinement) or just before development by imaginary applying it to the application.
The next big advantage of the Gherkin descriptions is the possibility of direct usage in the acceptance tests. You can just create
.feature file in the project and copy scenarios from the story. These files can be used by such tools like Cypress, Cucumber.js or jest with jest-cucumber plugin(the plugin doesn’t support the reports in the latest version, I hope it will be fixed soon, condition on 19-10-2022). So after copying scenarios you need to implement the steps, described in Gherkin and tests are ready.
In our team, we’re trying to follow TDD principles during the development, so we consider scenarios as acceptance tests for our app in all the cases. For our product owner, it’s a possibility to be sure that the feature is not only implemented but covered by tests.
Single language for the team and testing sounds serious enough, doesn’t it? However, it's not all benefits that you can take from Gherkin. I listed several items that seem valuable from my point of view:
- you see the size of the tasks immediately. By opening the task you will see a number of scenarios in it and this is a kind of mark of complexity. Of course, the scenarios themselves will not describe the complexity of the implementation, but in the majority of cases, the task with 10 scenarios will require more time than a task with only one.
- easiness of splitting the tasks. After several written stories, you will start seeing when you have too many scenarios in the story. Additionally, during the work over the description I'm grouping scenarios by some principle, so later if I decided to split it would be not that difficult. For developers, it’s also pretty clear, if they see 50 scenarios be sure they will request to split the story
- everyone can write and update the story descriptions. Many times in my past I faced the situation when I found new details that are not written in the description. Usually, it required some communication sometimes a pretty long, but now I'm just updating the story and asking PO about reviewing my changes. The same way it works for technical stories, they look much more understandable with Gherkin because it won't allow you to go to deeply into technical details
Let’s consider a more realistic example than opening the door to feel more confident with Gherkin. Imagine we have an online shop that requires a promo code system. Let’s say that the back-end is implemented and the online shop contains features of adding purchases to the cart and payment. Let's write a story for this feature:
As a shop user
I want to have the possibility to apply promo codes to my purchases
So that I can buy products at lower prices
Now we have the goal of the task from the user's point of view and anybody who opens this task can easily find the answer to the question "Why are we doing it?”
Time to write scenarios. Scenarios might be written before the grooming or refinement meeting and in that case, we're discussing them, clarifying all the details, updating them if it's needed, and estimating. In case we don't have scenarios in the task, we're writing them during the meeting.
Feature: Promo code functionality
Scenario: Promo code field is available on the cart page
Given I opened the root page of the shop
And I've added something to the cart
When I opened the cart page
Then I see on the right side the promo code field
And "Apply" button is visible
Scenario: Apply promo code
Given I opened the cart page with some purchases
When I specified a correct promo code in the promo code field
And clicked "Apply" button
Then I see the notification that promo code is applied
And total price is recalculated
And promo code field is empty
This is not all scenarios, but the main idea should be more or less clear. We actually have to add a scenario for statuses of the "Apply" button, if the code field is empty. Additionally, we have to describe what will happen in case of invalid codes. I think if you tried to write these scenarios you would face the repetition of some steps in several or all scenarios. Don't be afraid it is fully fine and even good because in tests you don't need to write code more than once. Moreover, you can use Background and Scenario Outline for simplifying you tests , but make sure that tests framework supports these keywords.
You can say: “Ok, but what if I need to change the scenario during the development?”. The answer is simple - do it. The main idea of whole this process is to make stories available for editing by team members. Just ask PO to verify changes after you've done them. Sometimes corrections might be applied in the review stage, but it's usually related to grammar or wording.
We're writing tests right away, so scenarios will be used immediately and the majority of changes will appear in the first hour of development. Often the only changes we made is adding new scenarios for covering things we missed.
Despite the fact that I consider Gherkin useful for development in general, there are some tips and tricks that I found while working with it, maybe it will be helpful:
- The goal of the task should be written before the scenarios and all of them should be consistent. We use “As a … I want … so that …” for describing goals(you can see it in the example above). It's an important thing because every person on the team will understand why you're going to do this feature
- Scenarios should not be too long, ideally, you will have only "Given", "When", "Then" steps. If this is not possible - add "And", "But" steps with additional details, but don’t overuse them (I would recommend not more than 3 such steps) to not lose readability
- Steps have to be short clear and unambiguous. I will not promise, that it will be easy to achieve, sometimes you will have to add some notes outside the scenario to make it more clear, but you need to pursue it. I use the Notes section for adding additional details, but again it should not be huge.
- Every scenario should have only one "When" step. It's necessary to make your scenarios atomic and simple to comprehend. If you need to describe several related actions you can add several "And" steps to your "When", but make sure that it's not different scenarios. if you have doubts - split it into several scenarios.
- I would not also recommend using the exact values of labels button names etc in Gherkin scenarios(not tests) if it's not necessary from the Business perspective side. Such values may make your scenarios brittle, after any changes, they become not actual anymore even though the behavior itself was not changed. If we're talking about the UI, from my experience, it changes regularly and such items as labels, messages, and button names are not good anchors. After some time scenarios with them won't be understandable to anyone. First of all, scenarios have to describe the application behavior, not the exact implementation. If you need to check that table has specific columns - just add the verification of it in the implementation of the steps and add a generic phrase to the scenario like this "Table contains proper columns". More about it might be found in this article - better gherkin
In our team, Gherkin was adopted fairly easily, but it doesn't mean that approach will work in such a way for every team. Badly written scenarios are hard to read and difficult to support. It might become a huge pain relatively quickly. You mustn't allow it to happen. It's better to spend more time writing fewer but good scenarios.
Writing and using scenarios it's a skill, that depends on the whole team. You need to have a really good level of communication between team members and aspirations for a better understanding of the business goals otherwise you won't be able to use Gherkin benefits.
Describing some of the features might be really challenging because it's difficult to place all the details in scenario form. For such cases, we're using Notes and splitting the work into simple chunks.
Gherkin helped our team with an understanding of our products and improved their quality and made our communication more productive. I can easily say which user scenarios are covered with tests in our projects and every developer can. We're kind of sharing the same vision of product across the team and that allows us to move faster with fewer gotchas.
At the same time, I would not consider this approach a silver bullet, because it won't solve problems instead of you. It requires some discipline and several iterations of enhancement to make this approach really useful, but if you asked me - I would answer "It's worth trying!"