BDD and Gherkin - You are doing it wrong!
The first and most important part of your test automation journey
๐ Delivering High-Quality Software: The Importance of Proper Feature Specifications with BDD and Gherkin ๐
The most important step in delivering high-quality software is writing proper feature specifications, achievable nicely with the help of BDD and Gherkin. However, chances are you're doing it wrong! This article aims to provide valuable insights to help you improve, which you can apply immediately after reading.
๐ Definition
Behavior-Driven Development (BDD) is a software development technique focusing on describing a feature by its behaviors. This approach leads to a deeper understanding of acceptance criteria, reducing uncertainty about requirements and ultimately aiding your team in delivering better software. Describing feature behaviors using Gherkin syntax facilitates collaboration within your team, involving testing from day one, even before development begins. Consequently, this process yields properly written, testable software specifications that can be automated.
There's much more to explore about BDD and Gherkin, but I'll leave that for you. Let's take a look into an example to illustrate the significance of properly written specifications. In this example, I am going to show you a feature file scenario, as it is a common artifact used for representing the outcome of the sprint discussions and they play a very important role in test automation frameworks, such as Cucumber or Specflow.
๐ ๏ธ Applying BDD
Misunderstanding it
Imagine you have a basic shopping cart feature to test. A common mistake is performing sprint refinement, adding acceptance criteria that appear satisfactory on the surface. However, testers often isolate themselves in creating a feature file for designing and automating testing scenarios, while developers proceed independently. This approach sets off on the wrong foot as BDD is meant to increase collaboration, not to segregate your team in independent working streams.
The right way
A better approach involves raising all relevant details during your three amigos session or sprint refinement for a given story in which the whole team participates and reaches out to the conclusions together. The team should then summarize these details into the acceptance criteria, with the help of Gherkin syntax for example. This not only provides crystal-clear information for the product stakeholders, but also offers precise implementation guidelines for developers. Additionally, it serves as a testing scenario for the testers.
In essence, the feature file is the product of the teams' discussion about a story and should serve as a testable written requirement that can be utilized by everyone. This is how you start off on the right footโby understanding what a feature file represents.
๐ Feature file example
Junior tester mistakes
Now that we understand how to run BDD and what is a feature file, we can continue with the shopping cart example. I want to show you how to design a good feature file, which should be just a high level description of the business rules. It is that simple, but many people make mistakes due to overlooking crucial differences between a bad and a good scenario. I will skip things like the feature name and description, scenario name, and the feature background. I will focus on what is important at this point, but be aware that a bad feature description or scenario name can drive you to failure at the very beginning.
Given I click on add item button
When I click on the shopping cart icon
Then The title of the screen is Checkout
And The system shows me the item
The first rookie mistake here is framing the scenario from the system's perspective. That is a bad practice because it makes the scenario difficult to read, as humans naturally understand things better if following steps from a human viewpoint instead of a machine perspective.
The second issue is that system-based definitions bring the steps closer to the low level implementation details and obscures business rules, increasing the complexity and the maintenance costs over time. We will explore that in more details later.
Senior tester mistakes
An experienced tester could advocate for parameterizing steps to enhance scenario reusability at all costs, assuming that a common steps library shared amongst the project classes can be used at different scenarios. I have seen that countless times, but let me illustrate that approach and discuss the issues:
Given I click on 'add item'
When I click on 'shopping cart'
Then I can see 'Checkout'
And I can see 'My item'
One significant issue is the lack of insight into application behavior throughout the test beyond a series of clicks and displayed items. This disconnect from the business rule and makes telling the difference between this and another "few clicks and information check" scenario very challenging. Also, developers or product owners will not be willing to engage in conversations about a testing scenario described like that. The result is that this will isolate your testers from the rest of the team, hence it will not help in delivering the high quality software you are looking for.
Secondly, detailing every single action that you perform in the application inflates scenario size beyond readability, introducing unnecessary complexity to a business rule description.
Finally, a big problem is that this approach tightly couples scenarios to implementation, requiring extensive updates for minor user interaction changes and increasing maintenance costs. Furthermore, as you have made all your scenarios look like a bunch of meaningless clicks, it becomes extremely hard to identify all the specific places where you may need an update.
The Clever Tester example
Now we will examine a well-crafted scenario, but I want to invite you to think about one question that you should try to answer by yourself before you read the next session about its perks: What makes it good?
Given I add 'my item' to my shopping cart
When I inspect my checkout items
Then I should find 'My item' included in the checkout
Perks:
Readability: This scenario is concise, facilitating quick comprehension. Moreover, you can see that the application domain is very explicit which ensure ease of understanding for all team members regardless their background.
Maintainability: By avoiding low level details, this scenario remains resistant to changes in how the feature is implemented e.g. user interface updates. It requires modifications only when the underlying business rule changes, and that is exactly where we want to be when it comes to updating test cases.
Reusability: While someone can argue this is lacking generic reusable steps, this scenario prioritizes readability over reusability, crucial for an effective testing artifact comprehensiveness. However, in another post I will get deeper into the implementation and I can show how we can have reusability properly applied in a test automation framework.
Big Plus: You can see that this scenario can support the entire team, like back-end or front-end developers, and testers, in accordance to what we have explored in the Applying BDD session, because it is not tied to specific implementation domains, but to the business domain! Consequently, it allows flexibility in testing automation approaches according to your testing strategy, such as via back-end only, front-end with back-end mocking, end to end testing, and so on.
๐ Conclusion
Starting testing automation without a deep understand of the above is a significant mistake. Regardless of your team's automation framework skills or tools capabilities, with the incorrect specification of testing scenarios from the beginning you will not generate the good results you expect. Failure to grasp this concept only leads to high maintenance costs and frustration, overshadowing the benefits of testing automation and demoralizing your team.