Specify Business Rules by Example

If you are going to use Specification by Example then start by specifying the business rules.

There are lots of ways to write scenarios within Gherkin – the language used to specify requirements in Cucumber – and I have a distinct preference for certain style. I advocate testing against business rules. This increases the robustness of the tests because they aren’t tied to a particular user interface (UI). It also means the tests run faster. And finally it lowers the cost of automated testing.

To ensure I get what I want I gave my current team four guidelines for writing their Gherkin scenarios:

  1. Define the business logic
  2. Use business language
  3. Pretend there is no user interface
  4. Focus on state

Define the business logic

Where to Specify by Example

Where to Specify by Example

Generally the product owner and business analysts know the business rules but the developers do not. So I want tests that make the business rules explicit. If the systems breaks the business rules then the tests should break. If the system meets the business rules then the tests should run green.

Scenarios articulating business rules have the benefit that the product owner, and other people from the business, are more likely to understand them.

Concentrating on the business logic also means you can test under the UI (e.g. via an API or service layer). The tests will run faster and be independent of specific UI elements (buttons and screens). The tests will apply even if there are multiple simultaneous UIs to the same thing e.g. add data via a web UI and add the same data via a mobile specific UI.

Use business language

A key part of Specification by Example is to achieve “Ubiquitous Language”, i.e. the business, tests and code all using the same terms. This aids communication between the various people on the team and between the team and the rest of the organisation.

Pretend there is no user interface

Everybody I’ve met that is new to Gherkin starts with an Imperative style of scenarios. This type of scenario fills in fields and clicks through screens. The Imperative approach is simple and intuitive and reflects what manual testers do.

But I hate the Imperative style with a passion. I find tests based on the specific UI to be brittle, expensive and slow. Not characteristics that are desirable in an automated test.

Here’s a real Gherkin scenario somebody on a previous team produced. The business domain is News production. Aside from the fact the Gherkin syntax is syntactically dodgy the scenario is terribly Imperative. There are a lot of specific references to the UI, e.g. pages, the “Save” button and the need to “click” it. None of which is about how the business operates. None of which particularly helps as UIs have a tendency to change. And although the business rule is in there, it is tied to that page and no other. Nothing is said about any other page where it might be possible to create a Diary Entry.

Health Warning: Do Not Try This At Home – Example Included Just To Illustrate What Not To Do

# Horrible imperative scenario showing bad practice 
Scenario: Minimum New Diary Entry
Given I am looking at a "New Diary Entry" page in the "West" diary
When I fill the following fields:
  | Field   | Information                        |
  | Slug    | Syria                              |
  | Summary | Syria air strikes target civilians |
And I click on "Save" button
Then I see the "West Diary" page
And I see a table of "DiaryEntries" in the "other" section with:
  | Slug / Angle | Location | Summary                            | People and resources | Content |
  | Syria        |          | Syria air strikes target civilians |                      |         |

To encourage a Declarative style of Gherkin I tell my team to pretend there is no user interface.

Focus on state

From my simplistic perspective business rules are constraints on how the state of the business is allowed to change. So I advocate Gherkin scenarios that focus on state. A simple template for that kind of scenario is:

# Template for state based business rule
Scenario: business rule in words
Given the current state relevant to the business rule
When I try to change part of the state
Then the state is different
  or the system complains about an error

Some people find the concept of state a bit tricky, so here is a template assuming a database is the repository. This is still the same state based logic, but just emphasising that the state of interest is the contents of the database.

# Template for business with database
Scenario: business rule in words
Given existing data in the database
When I try to add/update/delete some data
Then the data in the database is different
  or the system complains about an error

Now for the Declarative alternative to the Imperative scenario I gave above. The happy path is about creating a entry with only the mandatory fields; everything else is optional.

Scenario: Slug and Summary are mandatory and everything else optional
Given the "West" Diary is empty
When I add a Diary Entry to the "West" Diary with 
  a Slug of "Syria" 
  and Summary of "Syria air strikes target civilians" 
Then the "West" Diary has a Diary Entry with 
  a Slug of "Syria" 
  and Summary of "Syria air strikes target civilians"

The happy scenario should be complemented with unhappy scenarios. For example ensuring there is a Slug.

Scenario: A Diary Entry must have a Slug 
Given the "West" Diary is empty
When I add a Diary Entry with no Slug
Then the "West" Diary is still empty 
And a "Slug is mandatory" error occurs 

Notice that these scenarios apply to the entire system. So if there are alternative UIs (web + mobile) the same business rule applies to both. It doesn’t matter where in the system a Diary Entry is being added, it must always have a Slug.

This post is part of a series on Specification by Example.

One thought on “Specify Business Rules by Example

  1. The point that worries me in this approach (I have considered taking it as well) is that reuse of the steps can be very limited, because a lot of code is put into the actual implementation of a step. For example take the first Given: being empty may have a certain meaning in the context of the scenario, probably not having any entries. In the context of another scenario empty could very well mean that there are no reviewers or writers. That means that this become a way to write user story alike scripts, which is of great value, especially when you can automatically test them, but. Ahm. I don’t know.

Leave a Reply

Your email address will not be published. Required fields are marked *