Launch of the BDD Behaviour Specification Handbook!

In the world of Behaviour-Driven Development (BDD), today I am launching The Behaviour Specification Handbook! Please note that this handbook significantly supercedes the two previous blog articles I wrote on the subject - they were the genesis of this work.

Contained in this handbook is more than five years of learnings from practising and coaching BDD on enterprise software development projects. This handbook is my suggested, prescriptive methodology for writing Behaviour Specifications (also known as ‘scenarios’ in the Gherkin language), including tips and suggestions that have repeatedly proven to me to be worthwhile practices.

I hope the handbook helps you and your team to write better Behaviour Specifications and deliver successful solutions!

Behaviour Specification Writing Methodology - Part 2

Please note, as of August 2015, this article is superseded by the The Behaviour Specification Handbook

In my previous article, Behaviour Specification Writing Methodology - Part 1, I discussed the prerequisites for writing Behaviour Specifications / scenarios. This article elaborates on my tips and suggestions for the next stage - actually writing the Behaviour Specifications.

The Behaviour Specification Writing Meeting

After all the prerequisites have been satisfied (i.e. core business requirements are known and the initial, low-level technical design has been drafted), it is now time to write the Behaviour Specifications. Schedule a Behaviour Specification writing meeting!

Attendees

The attendees of the Behaviour Specification writing meeting should include a holistic cross-section of the development team, including all the actual people who will be developing and testing the given functionality. I will come back to this point later.

The types of roles that should attend the meeting include:

  • Technical Lead/Architect;
  • Business Analysts;
  • Test Analysts; and
  • Developers.

Actual business representatives may of course also attend and can be especially useful if the requirements are not as clear as originally thought coming into this meeting. Assuming however that the requirements are crystal clear, the business representative would only attend predominantly for their own benefit and understanding, or for team building reasons.

Background Context and Requirements Overview

Please encourage the meeting attendees to ask questions at any time, and note all relevant feedback.

Start the Behaviour Specification writing meeting with some background context about the User Story. A walk-through of the business process leading into this User Story and other relevant high-level information about the business is always useful to set the scene.

It is also beneficial at this stage to now explain and walk the attendees through the requirements.

Technical Design Overview

Now have a technical representative walk the attendees through the low-level, draft technical design. Referencing some of the previously mentioned requirements, the technical representative should highlight the initially proposed systems and components and their relevant interactions.

This is a fantastic opportunity for the entire team (yes, even the Business Analysts) to understand the technical design and lingo, and initially challenge the technical design.

Checkpoint

At this stage, let the attendees ask any more relevant questions and note all relevant feedback.

As necessary, evolve the technical design on the spot to cater for any issue that has been identified.

If there are significant issues with the requirements or technical design, then consider whether it is prudent to postpone the rest of this meeting.

What’s Happening In Our Minds?

Throughout all of the above overviews and discussions, each attendee has now learned valuable implicit knowledge. This is the reason why the attendees should be the actual people who will do the development and testing - because throughout this meeting they are being transformed into the experts of this business functionality!

As the team next proceeds to write the behaviours of each component, multiple team members from different roles and perspectives are mentally testing each behaviour against their understanding of the solution - fantastically optimizing the feedback loop and enabling the team to avoid mistakes and reduce costly, wastful effort!

The process of writing the Behaviour Specifications is an important time where the attendees actively engage their mind and further collaborate and communicate. The result of the attendees actively engaging in the process is the growth of their own tacit knowledge and expertise. Again, this is the reason why the attendees should be the developers and testers of this functionality, because they become the experts who can most effectively and efficiently perform the implementation work.

To Gherkin or Not To Gherkin?

The Gherkin language is the most widely used and recognised business-readable domain-specific language (DSL) for specifying behaviours. Behaviours are defined within “Feature” files. Each Behaviour Specification is a “Scenario”, which has a description, and then is further defined as executable steps, with each step beginning with word “Given”, “When”, “Then”, “And” or “But”. Depending on the platform, there are different tools for parsing and executing the Gherkin. For instance, there is Cucumber for Ruby, SpecFlow for .NET, jBehave for Java, Behat for PHP…

The new kid on the street is Gauge. In Gauge, behaviours are defined in “Specification” files that follow the Markdown syntax. Each Behaviour Specification has a heading, description and then is further defined as executable steps.

The main difference between the syntaxes used in Gauge and Gherkin is that the syntax used in Gauge is completely free and open. There is no “Given”, “When”, “Then” restriction like in Gherkin, and this flexibility can be a powerful draw card for some people.

However, with so much flexibility and power, there is the need for great responsibility and consistency - especially in an enterprise. In a medium or larger business or enterprise, consistency in language and style is important. If such a business were to use Gauge, the first thing the business should do, in my opinion, is to create a style guide to promote consistency between teams. And congratulations - now the syntax is restricted - and that flexibility is tamed.

In the end, we may as well have just used Gherkin. Sure, there are other cross-language features in Gauge that may pique your interest, but for my Behaviour Specification writing methodology, I am sticking with Gherkin. The recommendations presented here can apply to the Gauge syntax if you so desire.

Behaviour Specification Writing

Now that the requirements are understood by the team and there is general agreement that sufficient requirements are known and the draft technical design is sound enough, the process of writing the Behaviour Specifications can begin.

This behaviour writing process is best broken down into two phases - indeed, often it is worth working through these phases in different meetings, primarily to allow the attendees to have a rest in between:

  1. Identify and write all the Behaviour Specification descriptions; and
  2. Write the steps that would cause the desired behaviour to manifest.

All members of a software development team, including developers, analysts and stakeholders should be able to understand the Behaviour Specification descriptions and steps - because they should be written in commonly accepted business terminology. On a daily basis, the development team normally should be communicating with the rest of the business using accepted business terminology. Similarly the behaviours should be written in the same accepted business style of language (as much as possible). One result of this approach is the minimisation of the costs to train new staff.

This approach also promotes more consistent communication within the development and support teams - and even to the wider business itself. An example of communicating with a wider part of a business is a project team (the wider part) that engages an internal software development team. The project team certainly could be interested in the documented Behaviour Specifications of a system that the internal software development team authored. Whether other wider parts of a business would be interested is debatable, and I think it may only apply to businesses with quite a high degree of software development maturity.

As an overarching style guideline, I highly recommend that all wording used in a Behaviour Specification should only need to change if there is a change to the core business requirement - and specifically the wording should not need to be changed if there is a change to the implementation.

Finding the right words to use when writing a Behaviour Specification can be thought of sometimes as an “art” due to the delicate balance between not using language that is too technical or specific, and at the other end of the scale, using language that is too generic that the reader cannot grasp the essence or actual purpose of the behaviour. Finding this balance can be a challenge, especially for novices. The best advice I can give is to copy the style of existing behaviours that your team agrees are well-written.

Tip: Take samples of existing well-written Behaviour Specifications into each behaviour writing meeting and refer to them as necessary! It is often helpful to review these in the meeting to refresh everyone’s memory.

Behaviour Identification and Descriptions

Take each system or component that is represented in the low-level technical design, one by one, and answer the following question:

“Within the context, boundary and responsibility of just that component, what are the behaviours that component should perform in order to fulfil all the requirements?”

Generally, each Behaviour Specification should be focussed individually on a single purpose or business rule. By doing this, each behaviour becomes a building block of tested functionality. When writing the next behaviour, you now have a “line of trust” that everything so far is working as specified, and you do not need to re-specify the behaviour or functionality of those building blocks.

End To End Behaviours

In addition to specifying the behaviours for an individual subsystem/component, you should also specify a small number of behaviours of end to end functionality (remember the Test Pyramid!). I suggest these end to end behaviours would be specified in their own feature file, separate from the feature file for the each component, since these behaviours span multiple subsystems/components.

Start With “Should”

Describe each behaviour specification / scenario in a sentence, beginning with the word “Should”.

“Should” at the start of a sentence helps to focus both the author and reader clearly on the actual behaviour. Behaviours are described with verbs. The next word after “Should” is typically a verb… so this helps everyone reading the scenario description to quickly understand the scenario and how it may differ from others.

The behaviour specifications are both living, executable documentation as well as being classified as test assets. The behaviours also are the specification that developers should use when they write code. The only code that should be written by developers is code to satisfy a behaviour specification. No behaviour specification - no code. Importantly, behaviour specifications are NOT part of a formal, legal requirements document.

Each behaviour specification / scenario description is similar to a description of a system’s capability. A system’s capability is not described in terms of “it must/shall/will do XYZ” - that is how a “requirement” might be worded. Behaviour specifications are determined after the business requirements have been identified and agreed upon by stakeholders.

The scenario description is a specification of a system’s expected behaviour - how the system should behave, based on all current knowledge and understanding. Dan North, the originator of BDD, in Introducing BDD eloquently describes more about the usage of the word “should”:

“A more subtle aspect of the word should becomes apparent when compared with the more formal alternatives of will or shall. Should implicitly allows you to challenge the premise of the test: “Should it? Really?” This makes it easier to decide whether a test is failing due to a bug you have introduced or simply because your previous assumptions about the system’s behaviour are now incorrect.”

Use Present Tense

The scenario description makes more logical sense when written in the present tense, because it is the describing the most up-to-date, current, at the present time, expected behaviour.

Avoid Generic Verbs

Avoid the word “handle” or any other verb that is generic and hides the actual behaviour.

For instance, let us pretend that someone wrote the scenario description: “Should handle the situation when the total amount is not equal to the sum of all item amounts”.

The above scenario description has both positive and negative points. On the positive side, the “when” part is descriptive and is an easily understandable, differentiating condition for the scenario. On the negative side however, “handle” is not actually describing the behaviour that occurs under in that situation. What is actually meant by “handle”?

A better alternative is to be more specific about the behaviour. For instance, “Should error when the total amount is not equal to the sum of all item amounts”. Using “error” as a verb instead of “handle” clearly describes the actual type of behaviour that should be performed.

Positive and Negative Behaviours

All good test suites cover both positive / happy path and negative / sad path scenarios. Behaviour specifications are the same.

In my experience, prefixing the scenario description (even before “Should”) with “Positive - " or “Negative - " allows someone reading the behaviour specification or test report to quickly and clearly determine whether the behaviour is focussed on the happy or sad path.

Primary / Business and Secondary / System Behaviours

It can be useful for the purpose of general understanding to distinguish between two different types of behaviours:

  • Primary / Business Behaviours; and
  • Secondary / System Behaviours.

A Primary / Business-based Behaviour is a behaviour that has been defined as a direct result of trying to fulfil a core business requirement.

A Secondary / System-based Behaviour alternatively is a lower-level behaviour needed by a system in order to enable or support the functionality of a Primary / Business Behaviour. A Secondary Behaviour is in no way less important than a Primary Behaviour - in fact, from one perspective, one can think that a Secondary Behaviour is more important because a specific Primary Behaviour is dependent upon and cannot function correctly without the Secondary Behaviour.

Examples of Secondary / System Behaviours include:

  • Exception handling
  • Transaction concerns
  • Data storage and retrieval
  • Performance concerns
  • Auditing functionality

Unique Identifiers for Scenarios

When developers write new tests, modify existing tests and/or then need to run tests, it can be very useful to have a mechanism to easily identify and pick a specific scenario/test out of a list of many scenarios/tests. For instance, when developers are using their favourite IDE’s Test Runner, if they want to find a specific scenario/test to run (even after using search or filtering on @tags), a unique identifier for each scenario can really help a human to visually find a specific scenario and select it more quickly.

I recommend including an incrementing number into each scenario description, with the number starting at one in each feature file.

In addition, prepending the feature name (or a shortened, unique version of it) helps to make a behaviour specification uniquely identifiable across multiple feature files.

Including all of the above information in each behaviour specification description makes life for all team members significantly easier when someone needs to reference a specific scenario in a communication, or navigate through a list of behaviours outside of the context of a feature file. For the small amount of discipline required, you will be cursing yourself and other team members if it isn’t done and if you are the poor soul that now has to find a needle in a haystack. Just do it - it’ll be worth it!

The template I find most useful for a scenario description is:

1[FeatureName]-[Primary/Secondary]-01 - [Positive/Negative] - Should blah.

I acknowledge that at times this can become wordy, but in my experience the benefits of clarity with this approach have always trumped that small annoyance.

Feature Files

Zooming out from scenario descriptions within a feature file, let us now focus on other aspects related to the feature file.

File-System Folder Structure

I recommend grouping various feature files as appropriate into different file-system folders that follow a logical hierarchy. The top level of the hierarchy could be the name of an architectural capability or domain (a high-level grouping mechanism or category).

Subfolders could then be used for other logical groupings that make sense, and their names should include a verb (we are after all describing categories of behaviours). The subfolder / behaviour category name may describe the set of processes, actions, behaviour and activities that take place, and should be in business language - not implementation or system specific language.

Within the lowest-level subfolder are the feature files.

Below is an example folder structure:

 1Purchasing (top-level folder, also the name of a domain)
 2|
 3|---- ProcessingOrders (subfolder, a general category of behaviours)
 4        |
 5        |---- Shopping (subfolder, a general category of behaviours)
 6                |---- ManageShoppingCart.feature
 7                |---- CalculateShippingCosts.feature
 8                |---- ProcessPayments.feature
 9                |---- PlaceOrder.feature
10        |
11        |---- FulfillingOrders (subfolder, a general category of behaviours)
12                |---- PickOrderItems.feature
13                |---- ShipOrderItems.feature

The feature files for different subsystems typically will live in different code branches or projects within your source control repository. For consistency reasons, use the same folder structure for feature files across subsystems.

I also highly recommend not having whitespace in a folder or feature file name, as this can cause problems depending on the technology or development tools you are using.

Feature Name

At the top of a feature file is the feature name. I recommend making the folder hierarchy and grouping names part of the feature file’s feature name value.

Each behaviour specification within a feature file is written from the context of a system, subsystem or component. Including the name of that subsystem or component in the description is also very using information, for the sake of clarity. Trickily, you may find that you have the exact same behaviour description and Gherkin in more than one component (for example, in both the User Interface and the back-end service layer), but the behaviour actually has a slightly different meaning in each because it must be understood and considered from within the context and perspective of that subsystem/component.

The template I find most useful for the name of a feature at the top of a feature file is:

1Feature: [Hierarchy-LogicalGrouping]-[FileName]-[Subsystem/Component]

Here is an example feature name, for a User Interface component:

1Feature: Purchasing-ProcessingOrders-Shopping-ManageShoppingCart-UI

And here is the same example feature, this time for the corresponding component in the back-end of a system:

1Feature: Purchasing-ProcessingOrders-Shopping-ManageShoppingCart-ServiceLayer

In this example above, “Purchasing-ProcessingOrders-Shopping-ManageShoppingCart-ServiceLayer” is the “feature name” that you would include at the start of each behaviour specification description.


In my next article, I will discuss tips for writing the actual Given/When/Then steps of the Gherkin and about implementing the behaviours as automated tests.

Behaviour Specification Writing Methodology - Part 1

Please note, as of August 2015, this article is superseded by the The Behaviour Specification Handbook

[Updated in April 2015]

Overview

As a long-time advocate of Behaviour-Driven Development (BDD), and being the technical lead and coach of BDD enterprise software development teams for more than 5 years, I have tried many different variations of the process of BDD and the writing and implementation of scenarios. The following is my suggested, prescriptive methodology for writing Behaviour Specifications (also known as Scenarios in the Gherkin language), including tips and suggestions that have repeatedly proven to me to be worthwhile practices.

Why BDD?

There are many articles that discuss the beginnings and benefits of BDD, so instead repeating similar information, here are some good starting materials:

Prerequisites

There are two important prerequisite inputs to a Behaviour Specification writing session - the 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

Before your team meets to determine the Behaviour Specifications (typically for a User Story, if your team is following an Agile methodology), ensure that the requirements analysis is as complete as possible. 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 meeting.

During the behaviour writing meeting, 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 is wiser to postpone the meeting until the relevant details of the requirement can be determined.

If a team ever walks away from a Behaviour Specification writing session exhausted 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 behaviour writing.

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 meetings, please be careful to clearly communicate to your team that the Behaviour Specifications have been postponed and the team instead is now performing more requirements analysis. If your boss thinks the team has been “doing Behaviour Specifications” for days with none of the expected outputs produced because all the effort has been requirements analysis, then your boss is not receiving accurate information for tracking and planning purposes. It is unfair to tarnish the name of and blame the process of BDD due to an unfulfilled prerequisite. Additionally, it is counter-productive for stakeholders to start questioning the process of BDD because they incorrectly heard that BDD takes a long time and is difficult - when the culprit really was requirements 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 the “core business requirements” understood and documented before the behaviour writing meeting.

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. By iteratively asking “Why?” or “What is the real underlying business need for doing XYZ?” the “core business requirement” can be uncovered.

Below is a contrived example.

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

Why?
“Because we want to enter data for ABC and screen XYZ has related stuff on it.”

Why do you need the data for ABC?
“We need that data for ABC to calculate MNOP.”

Why do you need to calculate MNOP?
“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”.

It is this type of business language that I highly recommend be used in the Behaviour Specifications / scenarios - not implementation-specific language about a textbox!

I highly recommend that, as overarching style guideline, all wording that is used in a Behaviour Specification should only need to change if there is a change to the “core business requirement” - and should not need to be changed if there is a change to the technical implementation. If you follow this recommendation, your Behaviour Specifications will live and stand strong through the passage of time.

Draft Low-Level Technical Design Complete

After sufficient requirements have been gathered, the solution/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 that identifies the likely systems and components that will be involved in the story.

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


In Behaviour Specification Writing Methodology - Part 2, I discuss how to successfully run a Behaviour Specification writing meeting.