Everybody I’ve met that is new to Gherkin starts with an Imperative style of scenarios. The Imperative approach is simple and intuitive and reflects what manual testers do. But I hate the Imperative style with a passion. I favour a Declarative style of scenarios not least because a declarative style means I can test business rules. The UI is prone to change but the business rules tend to be more stable.
Imperative Style of Gherkin Scenarios
There is a good chance that if/when you start writing Gherkin you’ll start with an Imperative style of scenarios. They are simple and obvious but I avoid them.
Imperative scenarios tend to be long with very low level steps that drive the user interface. Lots of navigating to pages, filling in fields, and pressing buttons.
# Imperative example in the Cucumber book Wynne & Hellesøy (2012) Scenario: Redirect user to originally requested page after logging in Given a User "dave" exists with password "secret" And I am not logged in When I navigate to the home page Then I am redirected to the login form When I fill in "Username" with "dave" And I fill in "Password" with "secret" And I press "Login" Then I should be on the home page
The big problem is that most of that is noise and incidental detail in terms of what interests the business, the business rules. The focus on the user interface behaviour obscures and devalues the important bits. That in turn leads to bored stakeholders; they aren’t going to read the scenarios.
I find tests based on the specific UI to be brittle, slow and expensive. Brittle because the UI changes so the tests will have to change, often. Slow because the tests have to run through a browser. Expensive because the tests are brittle and slow.
None of these are characteristics desirable in an automated test.
Declarative Style of Gherkin Scenarios
In contrast the Declarative style of Gherkin scenarios describes what the user does not how they do it. No mention of the UI – I tell my team to pretend there is no UI. The product owner can and will read the scenarios because they are shorter, focus on the business rules, and use business language. Detail is pushed into the step definitions.
I’m going to rewrite the imperative example above but first it needs a deny scenario. This is the bad guy scenario. Mainly included so you see the difference with the good guy scenario that follows.
Scenario: Deny a guest access to restricted material Given I am an unauthenticated guest When I attempt to access restricted content Then I am denied access to the restricted content
Now for good guy scenario. This is the Imperative scenario from above rewritten in a Declarative style based on an example from Aslak Hellesøy: The training wheels came off:
Scenario: Redirect user to originally requested page after logging in Given I am an unauthenticated guest And I have a valid user account And I attempt to access restricted content When I log in Then I have access to the restricted content
Comment on Abstraction
From the title of a recent post by Liz Keogh you might think There’s no such thing as Declarative and Imperative. Liz’s point is that Declarative and Imperative only differ in the level of abstraction. Imperative Gherkin is less abstract, more concrete, whereas Declarative Gherkin is more abstract. But that difference is fundamental. As Liz points out, the more abstract nature of Declarative Gherkin is useful if you want to “capture some conversations with people who naturally speak in terms that don’t involve the UI”. That is exactly what I want to encourage.
Comment on the Declarative Example from the Cucumber book
I’m not entirely happy with the Declarative example from the Cucumber book.
# Declarative example from the Cucumber book -- Steven's not so keen on it Scenario: Redirect user to originally requested page after logging in Given I am an unauthenticated User When I attempt to view some restricted content Then I am shown a login form When I authenticate with valid credentials Then I should be shown the restricted content
I’ve got two problems with this scenario as written. My main grievance is the “login form” and being “shown” things. Smells of UI. My version of this scenario avoids the UI smells.
I also don’t like having two cycles of When/Then in the scenario. Just so you can compare apples with apples my version of the scenario with two cycles of When/Then is below. I don’t like it because it fully includes the deny / bad guy scenario and hence dilutes the real business rule being tested here, i.e. a validated user gets redirected to the content after login. My preferred scenario has only one When/Then pair to emphasise the business rule for the good guy. This is a style thing and you can choose what works for you.
Scenario: Redirect user to originally requested page after logging in Given I am an unauthenticated guest And I have a valid user account When I attempt to access restricted content Then I am denied access to the restricted content When I log in Then I have access to the restricted content
This post is part of a series on Specification by Example.
Hellesøy. A. (2011, 5 Oct). The training wheels came off. Author.
Keogh, L. (2013, 17 June). There’s no such thing as Declarative and Imperative. Author.
Wynne, M. & Hellesøy, A. (2012). The Cucumber Book: Behaviour-Driven Development for Testers and Developers. Pragmatic Bookshelf.