A lot of the FUD you read about Cucumber involves teams abandoning the tool because they think it adds a layer of extra work to the testing process. However, teams that go that route are missing a big benefit of plain text user stories: executable documentation that is readable by “the business”. The ultimate goal is to have the business (aka the stakeholders) actually collaborate on user stories so that a shared understanding of what needs to be built can be developed across the whole team.
In order to achieve that goal, however, Cucumber scenaios need to be written in a certain way. They need to read as conversational requirements, not a QA test plan check list. This style of writing has a name: declarative.
“Possibly the most common sentence type in the English language, declarative
sentences are used when you want to make a statement. Whether it’s a bold
statement or a simple fact, the sole purpose of a declarative sentence is to
give information. It always ends with a simple period. And if you’d like to see
an example of a declarative sentence, you don’t need to look any further.
Actually, every sentence in this paragraph is a declarative sentence.”
The most important part of that last paragraph is this: “the sole purpose of a declarative sentence is to give information”. This is why Cucumber is best suited to this style of writing. A user story’s entire purpose is also to give information.
Perhaps the easiest way to show a good user story style is by first showing an
antipattern. Here is a user story written in an imperative style. If you have
been using Cucumber for a long time, you might recgonize these steps as being
matched by the now defunkt
1 2 3 4 5 6 7 8
Sometimes this style can be useful. It can help tease out an implementation detail that the only documented way to log in is clicking the ‘Log in’ button, for instance. However, I think stories that are structured in a declarative method overall provide more value more of the time.
A declarative version of the story above might read like this:
1 2 3 4
The implementation details are largely gone from the story, and it reads a lot better.
Another example where an admin is merging two user accounts in an asset management system might read something like this:
1 2 3 4
Here’s another shorter example:
1 2 3
Other resources on declarative user stories
This style isn’t a new idea anymore. However, many of the teams we work with still fall into the imperative trap when a deadline looms or it’s unclear how to extract several steps into a more declarative one. For some more inspiration on the subject, take a look at a few posts from other experts on testing and BDD.
- Imperative vs declarative scenarios in user stories
- Declarative vs imperative gherkin scenarios for cucumber
And from the author of cucumber itself: The training wheels came off
We’ve had good luck with this more declarative style at Faster Agile. Stakeholders can better read and understand the requirements in a user story, and with this conversational and plain language tool to describe how the system is supposed to work, they also help write the stories more often too!
Taking it a step further
After conquering the verbosity and repetativeness of imperative stories, there’s still a nagging issue with the resulting step defintions. Using bare capybara as the underlying mechanism to interact with the DOM can lead to mutliple ways of targeting elements to fill-in and click. Even if a project tries to standardize on targeting only IDs or only label text, that code is still repeated in many places leading to a brittle test suite that is locked pretty heavily to the existing ID/class structure and/or label text.
Stay tuned for a future post where we’ll show how Faster Agile uses the Site Prism gem and the concept of “page objects” to encapsulate the DOM for any given page making it much easier to keep a Cucumber suite more decoupled from the DOM it’s driving.