Overview Of The Gherkin Language

« Table of Contents »
Previous « Developers: No Other Automated Tests!

The Behaviour Specification Handbook

Behaviour Specifications

Overview Of The Gherkin Language

Behaviour Specifications can be written in different ways, and the most renowned is with the Gherkin language.

The Gherkin language is the most widely used and recognised business-readable, domain-specific language (DSL) for specifying behaviours. Each behaviour is defined as an individual “Scenario”. A “Scenario” has a description that summarises the behaviour being specified. The behaviour is then further defined as a series of steps to be executed in the order in which they are written — just like the steps of a test case.

The syntax of the Gherkin language specifies that each step begins with one of the following keywords: “Given”, “When”, “Then”, “And” or “But”. The “Given” steps must be specified before the “When” steps, which themselves must be specified before the “Then” steps. The “Given” steps define the prerequisite state that is required for the behaviour to manifest. The “When” steps define how to initiate the behaviour being specified. The “Then” steps define how to verify that the behaviour performed as expected. Steps that begin with “And” or “But” merely allow for more details to be specified and extend the meaning of the proceeding “Given”, “When” or “Then” step.

The Behaviour Specifications are logically grouped as a “Feature”. A “Feature” also has a short description that summarises the scope of the logical grouping of behaviours. While not necessarily specific to the Gherkin language (it depends on the implementation of the tooling that parses the Gherkin language), each “Feature” typically is stored within a file with a suffix of “.feature”.

There are various tools in each different technology platform for parsing and executing the Gherkin-based “Feature” files. For instance, in Ruby there is Turnip, Spinach and Cucumber, in .NET there is SpecFlow, JBehave for Java, Behat for PHP, Gauge, and many others.


Next » Thoughts On Gauge

Prerequisites

« Table of Contents »
Previous « The Behaviour Specification Writing Process

The Behaviour Specification Handbook

The Behaviour Specification Writing Process

Prerequisites

There are two important prerequisite inputs for writing Behaviour Specifications — the business requirements and an initial low-level technical design. I cannot stress enough how important these prerequisites are to hosting a successful Behaviour Specification writing session!

Requirement Analysis Complete

Imagine that your team has just moved a User Story from the Backlog into an In-Progress phase where analysis is to performed and the Behaviour Specifications written. Before your team meets to determine and write the Behaviour Specifications for that User Story, ensure that the business requirements analysis is as complete as possible by having various conversations and workshops with all the relevant people, in order to gain enough clarity. Once the requirements are generally well-understood and an initial design is drafted, the team can proceed to actually writing the Behaviour Specifications.

The nemesis of a Behaviour Specification writing session is unknown, unclear or incomplete requirements. Unclear requirements are the primary cause of elongated discussions, frustration and confusion in a Behaviour Specification writing session. During the Behaviour Specification writing session, if missing requirements are identified, I recommend that you simply make a note of them for later and carry on — if possible. On the other hand, if there is a critical requirement missing, it could be wiser to postpone the session until the relevant details of the requirement can be determined.

If a team ever walks away exhausted from a Behaviour Specification writing session or thinking that the process is difficult, I can almost guarantee that there was a lack of requirements analysis performed before the meeting. The requirements gathering, analysis and clarification is the difficult work that requires and causes the most discussion, time, effort and agreement. Requirements analysis is thus defined as a prerequisite that should remain a very separate process from writing Behaviour Specifications.

I have witnessed many Behaviour Specification writing sessions turn into requirements analysis workshops. This in itself is not a bad thing — indeed the Behaviour Specification writing meeting has just succeeded in facilitating, identifying and initiating other important discussions. However, if this happens in your sessions, please be careful to clearly communicate to your team that the Behaviour Specification writing session has been postponed and the team instead is now performing more requirements analysis.

If the boss or various stakeholders think that the team have been “doing” Behaviour Specifications for days, with none of the expected outputs produced (because most of the effort has been requirements analysis and clarification), then they are not receiving accurate information for tracking and planning purposes. A possible next, unfortunate and counter-productive step is for the stakeholders to start questioning the overall process and value of BDD — so be careful! It is unfair to blame the process of writing Behaviour Specifications for delays that arise due to an unfulfilled prerequisite — when the culprit is a lack of requirements or business analysis.

Core Business Requirements

There are different types and ways of describing requirements. For the purpose of the Behaviour Specification writing meeting, it is most useful to have not just the business requirements understood, but the “core business requirements” understood beforehand.

A core business requirement has a clear purpose and business value, and it explicitly does not contain a description or specification of the implementation details.

If a “requirement” includes implementation detail, then there is the awkward situation where non-technical business colleagues are effectively dictating the implementation design to the technical experts. The technical folk however may think of a better implementation option, if they were empowered and given the opportunity.

Sometimes the “core” requirements are already known, but many times the author of a requirement has innocently encoded implementation-specific details within the requirement. A common example is with User Interface requirements. The User Interface requirement may, for instance, specify the need for a new textbox on a screen. That however is not a “core business requirement” because both “textbox” and “screen” are implementation details.

It is more beneficial to take these implementation-specific requirements and convert them back to “core business requirements”. The “5 Whys” principle can be used to find the “core” or root requirement. The “core business requirement” can be uncovered by iteratively asking “Why?” or “What is the real underlying business need for doing XYZ?".

Core Business Requirements — An Example of Iterative Whys

Here is a contrived example. Let us assume that the documented requirement is: “Display a new textbox on screen XYZ so we can enter data for ABC”.

Now let us iteratively ask “Why?” to find the “core business requirement”.

Q) Why?
A) Because we want to enter data for ABC and screen XYZ has related stuff on it.

Q) Why do you need the data for ABC?
A) We need that data for ABC to calculate MNOP.

Q) Why do you need to calculate MNOP?
A) To correctly invoice the customer.

With this understanding we can now state that the “core business requirement” is: “To receive information about ABC so that the customer can be invoiced correctly”.

That is the flavour of business language that I highly recommend be used in the documentation of requirements and Behaviour Specifications — not implementation-specific language about a textbox!

Initial Low-Level Technical Design Complete

After sufficient business requirements have been gathered and clarified, and before the Behaviour Specification writing session, the solution architects, technical architects, designers and gurus in the team should have met, discussed and sketched out an initial, draft version of a low-level technical design. This technical design should identify the systems and software components that are likely to be involved in the solution for the User Story. If an even more mature technical design can be determined, then even better.

During the Behaviour Specification writing meeting, the team will focus on defining the behaviours of each of the software components that were identified in this low-level technical design.


Next » The Behaviour Specification Writing Meeting

Re-use Steps, If Possible

« Table of Contents »
Previous « Terminology Guidelines

The Behaviour Specification Handbook

Effective Behaviour Specification Steps

Re-use Steps, If Possible

Behaviour Specification steps that refer to and perform the exact same underlying functionality should be implemented once and only once! Always try to reuse functionality where possible — if it makes sense to do so.

Some steps can be genuine cross-cutting concerns with reusable functionality that all software components within the same system may use. Examples of these include performing the actions for signing-in to a system with specific credentials or other utility style functionality such as logging or auditing.

Many steps however are typically specific and scoped to the context of the software component they refer to. These steps generally are only reused by different Behaviour Specifications within the same feature file. This is to be expected and is absolutely is fine!


Next » Understand Technical Tool Constraints

Review Test Outputs

« Table of Contents »
Previous « Separate Implementation Of Unit Test Steps From Integration Test Steps

The Behaviour Specification Handbook

The Implementation Process

Review Test Outputs

After completing the code and implementing the automated test for a given Behaviour Specification, the developer should sit down with a test analyst and take them through a review of the test output.

If the test analyst has any concerns, the developer should be willing to help and fix the issue until everyone is satisfied, and the test analyst is willing to sign off that behaviour as completed in the Test Management tool.


The End

You have reached the end of The Behaviour Specification Handbook. Thanks for reading, and I hope this handbook helps you and your team to write better Behaviour Specifications and deliver successful solutions!

Please leave any comments, feedback or suggestions in the comments section on the title page, or alternatively contact me on a social network.

Scaling BDD To Large Solutions

« Table of Contents »
Previous « Overview of Behaviour-Driven Development (BDD)

The Behaviour Specification Handbook

Background

Scaling BDD To Large Solutions

You may be wondering why and how I arrived at most of my recommendations. The short story is that I needed an approach that scaled up and worked for large, complex, enterprise-scale solutions and delivery teams.

The Problem

Many teams struggle to effectively apply BDD, mostly because of a lack of knowledge and understanding. It is easy to find examples of behaviours, especially on the reference documentation sites of the various BDD libraries and tools. Those types of examples may be fine for that tool’s documentation, demonstrations, presentations or small applications, however the style of many of those examples do not necessarily scale up and work well in more complicated software solutions.

An Enterprise-Scale Example

Have you ever worked in an enterprise solution delivery team where there are multiple systems, applications and components involved in a single User Story?

If you are not familiar with User Stories or working in an Agile fashion, then just think about working to deliver a thin, vertical, end-to-end slice of functionality that can be deployed into production to produce actual business value and thus appease the stakeholders.

For example, say that there is the following User Story.

1As an online customer
2I want to see a summary of all my incomplete orders
3So that I can effectively track my orders 

In true Agile style, accompanying this User Story, there also would be a bunch of associated Acceptance Criteria, but at the moment that is unimportant.

This story makes the business’s customers happy, resulting in higher retention rates and more business transactions. In turn, that results in measurable value to the business.

Hopefully the User Story makes sense to you — it sounds simple, right (although admittedly a little contrived!)? Unfortunately, software development in an enterprise typically is never as simple as one would like!

In this example, the technical solution that is required by an unspecified enterprise just happens to involve many different layers and technologies:

  • The HTML, CSS and JavaScript of the Web Application;
  • The RESTful API Controller layer of the Web Application;
  • A Service-Oriented Architecture (SOA) Business Service that integrates with a legacy Order Management System; and
  • A Web Service that is exposed by the legacy Order Management System.

This is not an uncommon technical landscape!

Which Behaviours?

From a behaviour perspective, there are many potential behaviours in the above example:

  • The visual behaviours of the User Interface — such as hiding and showing visual elements and displaying pretty animations;
  • The logic behaviours of the User Interface — such as performing screen navigation, calling the API Controller layer and handling errors;
  • The behaviours of the RESTful API Controller that calls the Business Service;
  • The behaviours of the Business Service that invokes the legacy Order Management System’s Web Service; and
  • The behaviours of the legacy Order Management System’s Web Service.

Before we go any further, let me ask you a quick question. When you thought of BDD in the context of this “simple” example of showing a customer their incomplete orders, which set of behaviours from the list above did you think of originally?

In my experience, many teams tend to focus just on the behaviours of the User Interface — after all, that is the focus of the User Story. When that happens, many of the benefits of BDD are not realised, and one or both of the following two issues typically occurs.

The first type of issue is that the team may think it only necessary to write Behaviour Specifications for the User Interface component. The behaviours in this case are then generally written in the style of End-to-End tests which typically focus on exercising multiple variations, combinations and boundaries of data. Unfortunately, that approach leads to the creation of an inverted Testing Pyramid with way too many expensive End-to-End style tests, compared with Unit Tests.

The second type of issue that could occur is a lack of quality assurance and test coverage of the entire solution landscape. If the team is only writing Behaviour Specifications for the User Interface component for example, this leads to a few quality assurance and maintainability questions:

  • How are the other systems and components in the solution being tested?
  • What tests are being written for those other components?
  • Is the Testing Pyramid being adhered to, and is testing being performed at the most appropriate level?
  • Are all of those test cases valuable, valid and correct?
  • Who knows about and understands the intended purpose of the other tests?
  • If they exist, are these tests duplicating testing effort elsewhere?
  • Who is implementing and maintaining those other tests?
  • How are the other tests being managed, communicated, executed and reported on?

Perhaps some developers are being professional and are implementing automated tests for the code they have written. Perhaps their tests are valuable, or perhaps a developer has gone off on a tangent and is wasting time and money (and nobody knows!). Part of the problem is that the team as a whole does not have enough understanding and visibility over the tests (especially Unit Tests) that developers write, and that can lead to wasted and duplicated effort, as well as negatively affecting team cohesion.

To best realise many of the benefits of BDD, all the behaviours applicable to a User Story should be specified — not just for instance, the User Interface behaviours.

About Story Splitting

One way to reduce complexity and help to manage the solution delivery of a project is to ensure that User Stories are sized optimally for the team and the sprint. In some cases, User Stories can be vertically split into smaller, narrower stories. We need to remember though that a User Story is typically a thin, vertical slice of functionality with its own separate and measurable business value. This particular User Story unfortunately cannot be squeezed thinner and there is no satisfactory way to split it into any smaller vertical slices.

One could of course split it horizontally into tasks, application layers or components — but that is not a recommended approach because each split item then would not by itself deliver measurable business value.

Manipulating the size of the User Story may change the current amount of work in progress, but in any case, there still will be many behaviours involved in the solution, and these still will need to be managed effectively.

About Managing Behaviours

The idea of splitting horizontally is not appropriate for User Stories, but it is an appropriate approach for logically grouping and managing Behaviour Specifications.

Decomposing a large solution or problem domain into a number of more manageable chunks is an age-old approach that scales up and works. The approach that I recommend is to decompose a solution into a number of significant software components, and then work on the Behaviour Specifications of each component, one-by-one.

In order to prevent confusion, each component should be considered individually, and the behaviours of each component should remain separated from those of other components. The alternative, for example, would be to mix the Behaviour Specifications of both the User Interface with the behaviours of the Business Service — but that would just create confusion.

This suggested approach scales, is manageable, reduces confusion and it has repeatedly shown that it works! In addition, each software component can be individually tested and reported on, and the Testing Pyramid can be maintained.


Next » What Is A Software Component?

Separate Implementation Of Unit Test Steps From Integration Test Steps

« Table of Contents »
Previous « Code!

The Behaviour Specification Handbook

The Implementation Process

Separate Implementation Of Unit Test Steps From Integration Test Steps

When implementing the automated tests, it is better to separate all the implementation steps of Unit Tests from the implementation of Integration Test steps, as having the code for both types of steps in the same code file can quickly become confusing. If you imagine a code file that mixes the concepts of mock objects with real calls to actual implementation, you can imagine the type of confusion that could ensue. For everyone’s benefit, please keep them in separate files and classes!

I recommend a file naming convention of “[FeatureFileName]UnitSteps” for the Unit Test step implementation, and “[FeatureFileName]IntegrationSteps” for the Integration Test step implementation. With SpecFlow, it is dead simple to apply a “Scope” attribute to each different class, so that the code in that class is scoped only to scenarios that have a “@UnitTest” or “@IntegrationTest” tag.


Next » Review Test Outputs

Single When

« Table of Contents »
Previous « Understand Technical Tool Constraints

The Behaviour Specification Handbook

Effective Behaviour Specification Steps

Single When

A single “When” statement helps both the reader and tester to focus on the specific, single-purpose behaviour under specification.

If you feel tempted to have an “And” or “But” step that immediately follows the “When” step, then consider moving some of that behaviour up into the “Given” section. Part of what you are trying to specify is likely to be more closely related to the initial conditions that are required to be in place to manifest the behaviour, rather than the specific action that triggers the behaviour.

On the other hand, in the case of specifying something that happens in parallel or concurrently, it might be perfectly valid to have an “And” or “But” step after “When”.

If you are tempted to have a step that contains the word or, then consider whether the Behaviour Specification should be split into two separate Behaviour Specifications that each are better focused on having a single purpose, or whether a table is appropriate.

Given” and “Then” steps with multiple “And” or “But” steps are perfectly fine and common – just ensure it makes sense and is appropriate.


Next » Guidelines For Examples and Data Tables

Software Component Context Is King

« Table of Contents »
Previous « General Tips

The Behaviour Specification Handbook

General Tips

The Software Component Context Is King

When identifying, reading or writing Behaviour Specifications, the context (knowing which software component within the solution is being specified) is the most important thing to understand. It is essential to have a clear understanding of the boundary and responsibility of each software component, otherwise the Behaviour Specifications cannot be correctly understood. This is one reason why the low-level technical design is an important prerequisite.

Be aware of and careful not to start specifying and mixing the behaviours of other components into the behaviours of the current one being defined. There lies the path of complexity and confusion! If you smell that you might be going off-track, go back to and revisit the question — “within the context, boundary and responsibility of just this component…".


Next » Avoid Specifying Internal Technical Implementation Details

Specify Component Interaction Behaviours

« Table of Contents »
Previous « Specify Relevant Business Capabilities

The Behaviour Specification Handbook

General Tips

Specify Component Interaction Behaviours

A Component Interaction Behaviour specifies the public knowledge ways in which other components can interact with the component being specified. These types of behaviours can be thought of as representing public endpoints and describing service contracts. Importantly, Component Interaction Behaviours do not describe internal-only, technical details of a component.

Component Interaction Behaviours — An Example

In this example, say that there is a requirement to develop a business service for processing a change to a customer’s postal address. Importantly, this functionality must be available to any application within the business as a standards-compliant Web Service call. In addition, this same functionality must also be invokable inside the business via a message subscription mechanism, for instance, where there is a well-known, specific type of message published to a message bus. The business has identified and defined a business event message for postal address changes that can be published to the message bus.

There should be two Component Interaction Behaviour Specifications defined in this situation — one for each different and public knowledge way in which other components may interact with this component. The Behaviour Specification Descriptions for this component thus could be:

  1. Positive — Should be exposed publicly as a standards-compliant Web Service; and
  2. Positive — Should be invokable when there is a business event about changes to a customer’s postal address.

The term “Web Service” is acceptable terminology in this case because:

  • it is the public knowledge mechanism by which other components may interact with it — this is not an internal only implementation detail; and
  • “Web Service” is a modern, accepted term in the business’s language glossary.


Next » Write One Specification For One Behaviour

Specify Relevant Business Capabilities

« Table of Contents »
Previous « Avoid Internal Technical Implementation Details

The Behaviour Specification Handbook

General Tips

Specify Relevant Business Capabilities

You may have noticed that the example descriptions in What Is A Behaviour Specification Description? explicitly specify the usage of an “address validation service”. In that example, an “address validation service” is a well-known, documented capability that exists within the business. The example descriptions are subtly referring to the logical capability that exists within the business — a service to validate an address — and not the physical, technical implementation of the service, nor the specific technical name of that physical service.


Next » Specify Component Interaction Behaviours