Introducing Gherkin Genie
Let’s face it, writing clean and understandable tests is no easy task. And although Behavior Driven-Development (BDD) and feature files provide an exceptional opportunity to improve test quality, they often result in one extra level of complexity for developers. That means that they become more a liability than a benefit. But what if there was a simpler, more intuitive way to utilize these feature files? And what if this method also encouraged clean coding practices? Here comes Gherkin Genie. One of the most simple to use libraries that will make you reconsider your testing strategy.
Let’s cut to the chase: Instead of a long-winded introduction, we’re diving straight into an example. So you can start in less than one minute.
- Add the ‘gherkin-genie’ npm library to your project.
- Create the feature file.
- Import and
wish('./Your.feature')to create the test.
- Copy & paste the code given by the test.
- Fix the code.
It is as simple as that.
The inception of the library
The software development sphere is filled with toolkits, libraries, and frameworks, all aiming to make the development process simpler and more effective. Yet, sometimes, more than libraries, the complexity relays on finding the right mindset and how to react to the minutia to make the process the more straightforward possible.
Because of it, some months ago, I published a series of articles showing how, step by step, we could extract the best potential of the BDD style of programming. The idea was simple: I write a small kata that you have to reproduce, so by following it steps by step, you end up with a new set of techniques to improve your testing. And because it was BDD, a tool created by Dan North to teach TDD, it made it easy to separate the objective of the test, from the code of the test. It opened new doors, like using the same feature file to test the frontend and backend.
Unfortunately, there were not many other alternatives to choose from. Many provided they own test runner, often with fewer utilities and less efficient than Jest, or they were immature or complex.
In the first inspection of ‘ jest-cucumber’ I almost decided not to use it. Although it allows each test to use their own definitions, so it works better in the unit test paradigm, it makes you to almost replicate every automatable step from gherkin. However, going deeper inside the library API, I discovered that the community provided a new method to use the library that overcome that limitation.
It seemed good enough, but yet, all the library was screaming to use it in another way. It had some good points, like a failing step gave you some code that you can reuse, but with time, I realized that it still had a lot of overhead for the developer.
Teaching in the university
While I was writing those articles, I was also teaching in the university how to develop whole projects —back and front— using BDD and continuous delivery. And it was, in fact, the sixth year that I was giving that course. Furthermore, it was the sixth iteration of improving it.
To help you understand the evolution, I will describe how the course looked and evolved each year. From the first year, up to the sixth year:
- No testing at all. Students were grouped in sets of four, and groups should collaborate in pairs because each one developed a different part of one solution. With no testing, and forcing teams to collaborate, the result was not very satisfactory.
- TDD mandatory, but without a source of truth. I removed the group pairs concept, and I enlarged groups from 4 to 6. I also made TDD mandatory, so they started creating tests. Unfortunately, I saw that most of the tests were created after the code —so no TDD—, and the quality of them was very low.
- TDD with source of truth. This change came after recalling that, many years ago, I had read about a tool called blossom.io. This tool proposed writing a blog about what will be released as a development methodology. And each post, would be one development feature. So, I decided to put it in practice, and ask the students to write first a post with the functionality to implement. In addition, as a source of truth, I created a tool to generate a text that could be manually copy-pasted to the post, that would be the common ground. It was a half-baked BDD solution.
- Improving glue code. I preserved the idea from the previous iteration, including a system of snapshots to simulate back-front communication. I also drastically simplified the glue code, and the necessary code to create unit tests. Yet, this time that the friction for the students was even greater. Probably it was because it was a different class of students the reason why the friction grew, although the tools were simplified. Anyway, I took the message and I decided to simplify the environment once again.
- Self created glue code. Instead of having the students create the glue code, a tool would write the code for them. Moreover, it would be done without the use of regular expressions, taking advantage of what they knew about object-oriented programming, and performing a bunch of additional checks to aid in the writing. Another improvement was the full adoption of Continuous Delivery, with trunk development, and requiring them to deliver scenario by scenario instead of feature files. All in all, it was a resounding success, zero friction, 100% results.
During this last sixth iteration, they liked it so much, and felt so comfortable, that they started asking me how to do the same at their jobs. That is why I started to create that series of articles about how to do BDD. The idea was to teach them, and others, how to do the same with existing tools.
Funny story: I had a repeating student who was the terror of his group in the third year. Every time he added some feature, he broke everything else, but the incredible thing was that the tests were still passing. I spent many hours re-stabilizing that group’s project time and again. Now, after the student failed and had to repeat the year, he encountered the fourth year which had changed how to do the tests, practically adopting BDD. This time, the tables turned. It’s not that he had learned to write better code, it’s that the new tests were so robust that every time he broke something, the CI failed and he couldn’t commit. At that moment, he had to make an effort to learn to program well, and finally managed to pass.
The emergence of Gherkin Genie
The problem about ‘jest-cucumber’ turn out not to be the best tool. It looks like more the solution in the fifth —or even fourth— year. And seeing how it worked, and how people work with it, I realized that I needed a better tool, taking advantage of what I learned in the sixth year.
My ideal was just repurposing my code from the sixth to create that tool. But it was not possible.
The simple reason is that I cannot make a tool to create tests in any other repositories, that is dangerous and may not adapt to every convention.
So, I decided to create a new tool to run Gherkin tests. This tool would preserve the speed and versatility of test runners like Jest, Vitest or even PlayWright, with capacity for simple dependency injection and code reuse, but at the same time, without the need of any regular expressions and automatic code creation.
I took the idea of writing the glue code when a test failed from ‘jest-cucumber’, I elevated it to add more flexibility, simplified the API, and Gherkin Genie was born.
As someone who appreciates elegant, clean code, and resilient testing, I am thrilled to introduce Gherkin Genie.
It was born from several years of iterations, learning how to improve test and code quality, and making a great developer experience. And now, that I have Gherkin Genie, I see how it eliminates the complexities of regular expressions, makes Gherkin more accessible and effective, while focusing on enhancing the overall user experience. It also generates readily usable code with minimal effort, bypassing the common pitfalls and inefficiencies associated with traditional Gherkin use.
So, how can it help you:
- Simplicity: Gherkin Genie reduces the complexity involved in mapping Gherkin feature specifications to test steps, by using a straightforward mapping of Gherkin steps to class methods. By avoiding regular expressions, which can sometimes be confusing, especially for those new to the concept, it aims to simplify the process.
- Versatility: The library supports virtually any Gherkin features including docstrings, tables, and scenario outlines. It also handles steps across different classes, which would be beneficial for large projects where different steps might be handled by different classes.
- Automatic test generation: Gherkin Genie automatically generates tests based on the steps defined in a Gherkin feature file. The generated tests are formatted in a way that makes it easy for users to understand what needs to be implemented. The automatic conversion of Gherkin steps to method names in camel case is another helpful feature.
- Automatic parameter parsing: Another feature that stands out is the automatic conversion and passing of parameters. Gherkin Genie is able to parse numbers, strings, tables, and doc strings from Gherkin steps, and automatically pass them as parameters to the corresponding methods.
- Less boilerplate: While almost every Gherkin tool forces you to add some kind of annotation explaining how to parse steps, Gherkin Genie uses convention over configuration. Gherkin Genie employs a set of smart defaults and conventions, eliminating the need for repetitive and time-consuming boilerplate code. This approach encourages developers to follow standardized practices and makes the code more readable and maintainable.
- Support for multiple step definitions: In larger projects, Gherkin Genie provides support for having multiple step definition classes. This helps in organizing the tests better and can also lead to more maintainable and scalable code.
- Meaningful error messages: In addition to the automatic error messages for unimplemented steps, which is a significant time saver and a convenience feature, it also provides clear error messages explaining where the test failed. That accelerates the TDD test development loop.
- Custom Test Runners: Gherkin Genie supports custom test runners. It defaults to using the global
testfunction, the one that Jest uses, but can be configured to use any test runner. Including your favorite one.
- Teaching Aid: As noted in the provided background, Gherkin Genie was emerged from the teaching environment, aiming to help students better understand and implement Gherkin-based BDD. This nature is very useful when we are adopting BDD for the first time, or when in our team we have new members with little or almost not experience at all with BDD.
In general, Gherkin Genie is a good option for teams that are already using or interested in using Gherkin and Cucumber for their tests, and are looking for a more streamlined and less complex way of doing so.
In the landscape of modern software development, one of the daunting tasks faced by developers is implementing clean, understandable, and scalable tests. Here, Gherkin steps into the spotlight, promising a language designed to keep your tests clear and concise. However, it’s common to encounter complications in its adoption, particularly when wrestling with complex regular expressions or figuring out suitable names for step functions.
Now, thanks to Gherkin Genie, we have a new tool crafted to enable you to utilize Gherkins with minimal effort and maximum clarity. This library is not only a solution to remove the ambiguity of Gherkin usage, but it also saves your time, providing ready-to-use code snippets that you can directly implement in your projects.
The advantage of Gherkin Genie is twofold: it simplifies the way you use Gherkin, and it enhances your efficiency as a developer. For those already acquainted with Jest or similar test runners, integration is seamless. By simply installing the package, Gherkin Genie enables developers to quickly construct feature files, run tests, and analyze outputs, complete with code suggestions for unimplemented steps. It offers a new pathway to achieving clean, maintainable code, without the tedium of regular expressions or the uncertainty of crafting step functions. Gherkin Genie’s greatest allure, however, lies in its user-centric approach. The feedback it provides is not just accurate but actionable, empowering developers to focus more on creating value and less on wading through syntax.
Just install with
npm i gherkin-genie and give it a try. You will find it very useful and powerful.
For more information and learn how to use it, the documentation is available on its GitHub public repository:
Thanks for the read. I usually like to write stories to think about how we understand and apply software engineering, and to make us think about what we could improve. And this time, I want to contribute with a new way of testing. If you liked the article, check my most successful stories on Medium to read more.