ATDD: Using Cucumber/Gherkin for API, SPA, and Mobile

Dave Jackson Development Technologies, Testing Leave a Comment

Attention: The following article was published over 9 years ago, and the information provided may be aged or outdated. Please keep that in mind as you read the post.

I’m a big proponent of Acceptance Test-Driven Development (ATDD). The most successful projects on which I have worked have utilized some variant of ScrumAnd, one particular family of ATDD frameworks fits nicely within the Scrum User Story paradigm: Cucumber and Gherkin, its business-friendly Domain Specific Language (DSL).

In this blog I will provide an introduction to three effective tools for building quality software that meets or exceeds expectations, including Gherkin, Cucumber, and Specification by Example.

User Stories

For anyone not familiar with Scrum User Stories, they follow a simple format:

As a [user role] I want/need [some feature] So that [some business value]

For example:

As a Calendar App user
I need to schedule an appointment
So that I am reminded when and where I need to be

In this example, we’re working on a Calendar App and the feature requirement is the ability to schedule an appointment. The required result of scheduling an appointment is that the user is “reminded” of that appointment – specifically when and where it is.

At a high level, this is purposely somewhat vague, but the details are defined in the Acceptance Criteria of the story. These criteria answer the question “How do we know that this feature is complete?” This is where the Gherkin DSL comes into play.

Gherkin DSL

Like Scrum User Stories, Gherkin Acceptance Tests follow a simple format:

Given [some precondition] When [some event occurs] Then [some result is expected]

Following our Calendar App example, our acceptance test might look something like this:

Given I am an authenticated user
When I schedule an appointment for a specific time and place
Then the appointment shows up on my calendar

This test definition is still somewhat vague, so I prefer taking things a step further using Specification by Example, a technique that uses actual example data to define acceptance criteria.

Remember that this criteria is supposed to answer the question “How do we know that this feature is complete?” Without specific examples, what metric can we use to answer that question definitively? Let’s revise our test so that it looks like this:

Given I am an authenticated user
When I schedule an appointment for tomorrow at 8:00 AM in Conference Room B
Then the appointment shows up on my calendar

The “specific time and place” are now explicitly defined so we can validate our expected result. As you may have guessed, it logically follows that we can define other scenarios where the user doesn’t traverse the “happy path.” For example:

Given I am an authenticated user
When I try to schedule an appointment for yesterday at 8:00 AM in Conference Room B
Then I receive the error message “You cannot schedule an appointment in the past.”

We can also define other error scenarios such as missing date/time and/or location. In each scenario, specific examples will give us the means to definitively validate our expected results.

These test scenarios are looking much better than our original. However, the method of scheduling an appointment and the format of the expected results are still somewhat vague. This is because they depend on the system under test. In other words, the specific scheduling methods and results are different for the API server and the Mobile app, for example.

Platform and Language Differences

This brings us to another consideration: how do we test systems on different platforms written in different languages? The Gherkin syntax is platform and language agnostic, but it doesn’t actually define running code to execute our tests.

Let’s say for example that our API server is written in Ruby and our mobile app is written in C# using Xamarin. Fortunately, this is where Cucumber really shines. You implement Cucumber scenario step definitions in the language of the system under test, and most of the popular languages are supported.

For an API I wrote in Ruby and Sinatra, I used Rack::Test which allowed me to exercise the API synchronously in-process to keep things simple. Of course, any HTTP client library in any language can be used to exercise your API asynchronously, out-of-process, and across the wire. Adding Cucumber to the mix helps document the fact that your endpoint works as expected.

You’re probably wondering “Who’s the ‘user/role’ in an API scenario?” Fortunately, Cucumber works just as well testing machine-to-machine interfaces as it does for testing human-to-machine interactions. Simply replace “authenticated user” with “authenticated API client.”

Mobile or SPA

So, we’ve talked about how we can test APIs, but what about Mobile or Single Page Apps? I’ve been experimenting with Calabash for C# mobile apps on Android and iOS. It looks very promising as it can simulate gestures, check the state of the screen and capture screenshots when expectations are not met.

For SPAs, I’m looking into Pioneer for in-browser testing, but of course, there’s Cucumber-JS which can also run headless using Zombie.

Final Thoughts

In my experience, Gherkin, Cucumber, and Specification by Example are three effective tools for building quality software that meets or exceeds expectations.

For more information on Cucumber, I highly recommend The Cucumber Book. Examples are in Ruby, but easy enough to pick up if you’re not familiar with the language. Good luck!

— Dave Jackson, [email protected]

4 1 vote
Article Rating
Notify of

Inline Feedbacks
View all comments