Master
ThoughtWorks
Menu
Close
  • What we do
    • Go to overview
    • Customer Experience, Product and Design
    • Data Strategy, Engineering and Analytics
    • Digital Transformation and Operations
    • Enterprise Modernization, Platforms and Cloud
  • Who we work with
    • Go to overview
    • Automotive
    • Healthcare
    • Public Sector
    • Cleantech, Energy and Utilities
    • Media and Publishing
    • Retail and E-commerce
    • Financial Services and Insurance
    • Not-for-profit
    • Travel and Transport
  • Insights
    • Go to overview
    • Featured

      • Technology

        An in-depth exploration of enterprise technology and engineering excellence

      • Business

        Keep up to date with the latest business and industry insights for digital leaders

      • Culture

        The place for career-building content and tips, and our view on social justice and inclusivity

    • Digital Publications and Tools

      • Technology Radar

        An opinionated guide to technology frontiers

      • Perspectives

        A publication for digital leaders

      • Digital Fluency Model

        A model for prioritizing the digital capabilities needed to navigate uncertainty

      • Decoder

        The business execs' A-Z guide to technology

    • All Insights

      • Articles

        Expert insights to help your business grow

      • Blogs

        Personal perspectives from ThoughtWorkers around the globe

      • Books

        Explore our extensive library

      • Podcasts

        Captivating conversations on the latest in business and tech

  • Careers
    • Go to overview
    • Application process

      What to expect as you interview with us

    • Grads and career changers

      Start your tech career on the right foot

    • Search jobs

      Find open positions in your region

    • Stay connected

      Sign up for our monthly newsletter

  • About
    • Go to overview
    • Our Purpose
    • Awards and Recognition
    • Diversity and Inclusion
    • Our Leaders
    • Partnerships
    • News
    • Conferences and Events
  • Contact
Global | English
  • United States United States
    English
  • China China
    中文 | English
  • India India
    English
  • Canada Canada
    English
  • Singapore Singapore
    English
  • United Kingdom United Kingdom
    English
  • Australia Australia
    English
  • Germany Germany
    English | Deutsch
  • Brazil Brazil
    English | Português
  • Spain Spain
    English | Español
  • Global Global
    English
Blogs
Select a topic
View all topicsClose
Technology 
Agile Project Management Cloud Continuous Delivery  Data Science & Engineering Defending the Free Internet Evolutionary Architecture Experience Design IoT Languages, Tools & Frameworks Legacy Modernization Machine Learning & Artificial Intelligence Microservices Platforms Security Software Testing Technology Strategy 
Business 
Financial Services Global Health Innovation Retail  Transformation 
Careers 
Career Hacks Diversity & Inclusion Social Change 
Blogs

Topics

Choose a topic
  • Technology
    Technology
  • Technology Overview
  • Agile Project Management
  • Cloud
  • Continuous Delivery
  • Data Science & Engineering
  • Defending the Free Internet
  • Evolutionary Architecture
  • Experience Design
  • IoT
  • Languages, Tools & Frameworks
  • Legacy Modernization
  • Machine Learning & Artificial Intelligence
  • Microservices
  • Platforms
  • Security
  • Software Testing
  • Technology Strategy
  • Business
    Business
  • Business Overview
  • Financial Services
  • Global Health
  • Innovation
  • Retail
  • Transformation
  • Careers
    Careers
  • Careers Overview
  • Career Hacks
  • Diversity & Inclusion
  • Social Change
Software TestingLanguages, Tools & FrameworksTechnology

Applying BDD acceptance criteria in user stories

Dennis Hee Dennis Hee

Published: Jun 17, 2019

We often focus a lot of our time on creating narrative as a best practice approach to writing user stories. For example, “As a... I want to… So that...”

Don’t get me wrong, the user story narrative is critical to conveying the purpose and value of a user story. Here’s just one of many resources online explaining the advantages of a user story narrative, and how well written user stories help product owners communicate features to the team. But is it not, as important, if not more important, to discuss the acceptance criteria in a user story?

Well written acceptance criteria reduce the requirement-build gap that often falls through the cracks of communication. One of the industry-recognised best practices in writing acceptance criteria is the Behavior-Driven Development (BDD) format. As BDD gained popularity among agile practitioners, some common misconceptions started to appear.

The goal of writing in BDD format

There are many resources out there explaining BDD misconceptions, and its relationship with Gherkin and cucumber automated tests. In essence, we use the BDD format to ensure the syntax detailing the requirements, is close to the syntax an engineer would use to write and execute tests.

Like the Agile Manifesto and principles, in which these guidelines explain why we do and think the way we do, BDD is often misinterpreted. For example, how many times have we heard the statement 'we’re not doing documentation because we’re working agile!'

Three women working around a table

A lightning quick recap of BDD

As this is not another how-to-BDD blog post, I assume we're on the same page as far as the basic principles are concerned.

That is:
  1. 'Given' is the precondition(s), state, parameters relevant to this particular scenario. Setting the scene.
  2. 'When' is a trigger, or a state change, the thing we’re testing
  3. 'Then' is the expected outcome(s) of the trigger given the context of the preconditions

Common mistakes anti-patterns in BDD

'Mistakes' is a debatable word in this case, and here’s why. Since we use BDD for its similarity to natural language, it is often thought that if a BDD statement is grammatically correct, i.e. flows off the tongue of a native English speaker, it should be correct.

And since we value 'working software over comprehensive documentation', it shouldn’t matter much as long as the team understands it right? Debatable.

So brace yourselves, grab a stress ball, keep sharp objects away, and let’s dive in and look at some of the common BDD anti-patterns. 

Not a matter of if, but when

Here’s one misconception that is most commonly found:
Given the Form is submitted
When the value entered in the Number text box is not numerical
Then an error message “Please enter a numerical value” appear
 
While this no doubt rolls off the tongue and can be easily understood, it clearly violates the basic principle of the Given-When-Then format.

A better way to write this could be: 
Given the value entered in the Number text box is not numerical
When the Form is submitted
Then an error message “Please enter a numerical value” appear.

At this point, you might be thinking “Big deal! You say to-may-to, I say to-mah-to! Right?” Well not really. Imagine writing a similar scenario that validates a text box only if the user is logged in.

If we follow the incorrect example:

Given the value entered in the Number text box is not numerical
When the Form is submitted
Then an error message “Please enter a numerical value” appear
Given the User is logged in ← Condition
And the value in the Number text box changes ← Trigger
When the value in it is not numerical ← Condition? Trigger?​
​Then an error message “Please enter a numerical value” appears

This further blurs the lines of precondition and trigger, which actually voids the purpose of a clearly defined BDD format.

To explain this point further, if we don’t care about what goes where as long as it is comprehensible, why not just throw away the 'Given' clause entirely?

When the User is logged in
And the value in the Number text box changes
And the value in it is not numerical
​Then an error message “Please enter a numerical value” appears. ​

To really conform to the BDD format, a better way of writing this could be:
Given the User is logged in
And the value in it is not numerical
When the value in the Number text box changes
​Then an error message “Please enter a numerical value” appear

When When When 

Following the anti-pattern of mixing up between a precondition (Given) and trigger (When), we sometimes see people writing multiple statements of 'When' using the 'And' operator.

Here’s an example where it's incorrect:
Given I’m at the sign-up form
When I enter my details
First Name
Last Name
Email
Password
​And I submit the Form
Then an account is created
And account name is set as my Email
And a confirmation email is sent to me

So, what exactly is the behavior we’re testing here?

Is it the behavior of entering a First Name? Entering an Email? Entering a password? Or is this testing the behavior of submitting sign up details?

What about the validity of these fields entered? Granted, these questions could be easily answered by a simple conversation with the team. After all, story cards act as a pointer for conversations.

However, imagine these conversations at scale, for every acceptance criteria of every story. Ideally, acceptance criteria should be written as unambiguously as possible, so that we reserve conversation time for more complex matters. There are bigger fish to fry.

Two colleagues discuss story cards

The When clause should only contain a single trigger, and the Given clause should list all the conditions that have an impact to that trigger.

For Example: 

Given I’m at the sign up form
And all these mandatory fields are entered

  • First Name
  • Last Name
  • Email
  • Password
When I submit the Form
Then an account is created
And account name is set as my Email
And a confirmation email is sent to me

The clear distinction between these two examples is that the right example has a clear trigger, i.e. submission of the form; with a clear precondition, i.e. the fields are validated; the wrong example has a sequence of events in the trigger.​

Precondition vs sequence of events

While we aim to be unambiguous when writing user stories, we could possibly go overboard and fall into the pitfall of over-explaining.

Take the example of a scenario to reconfirm a flight seat selection: 
Given I have selected a flight at the Flight Selection page
And I chose to skip seat selection at the Seat Selection page
And I selected a meal at the Meal Selection page
When I confirm my details on the Confirm Details page
Then a warning message should appear “Seat will be assigned randomly, proceed”.

Again, at first glance, this looks right, and frankly, it is not hard to write acceptance tests for this. Yet, there is a simpler, and better way of writing the same scenario: 

Given I’m at the Confirm Details page   
And I had opted to skip seat selection
When I confirm my details on the Confirm Details page
Then a warning message should appear “Seat will be assigned randomly, proceed”

​In this example, the precondition section first sets the context, then mentions the only precondition that matters in this scenario. 

This simplification is done because in this case, these things do not matter:
  • The flow and order in which the user arrives at the Confirm Details Page
  • The actions and parameters (other than skipping seat selection) the user has done before this
By making this particular scenario or test cover as few stages as possible, it makes it less brittle to future changes and often requires fewer tests to cover all scenarios.

As unit tests go – we test the smallest piece of individual functionality.

Final thoughts

While I am no self-proclaimed BDD expert or wanting to lecture fellow practitioners on this subject, I am, however, a strong believer that “technically correct is the best kind of correct”.

When Dan North pioneered BDD, there were reasons that Given-When-Then were confined to the definition of Precondition-Trigger-Outcome. Some of these reasons extend to test principles like Arrange-Act-Assert and Four-Phase Tests.

After all, a well-written acceptance criteria serves two purposes. Firstly, it is to articulate with clarity to a non-technical audience that the criteria will be used to validate a feature’s behavior. Secondly, and equally important, it is to ensure that this requirement can be easily transformed into building and testing code. BDD happens to be a good medium to address these outcomes.

Given these reasons, I believe that while the readability of the BDD statements is important, there is value in advocating for the right way of writing BDD statements that stick closely to the format of Given Precondition(s) - When Trigger - Then Outcome(s)
Related blogs
Software Testing

Test Driven Development is the best thing that has happened to software design

Arek Torczuk
Learn more
Transformation

How BDD and Feature Injection can help you be a better...

Elena Yatzeck
Learn more
Software Testing

3 misconceptions about BDD

Juraci Vieira
Nicholas Pufal
Learn more
Master
Privacy policy | Modern Slavery statement | Accessibility
Connect with us
×

WeChat

QR code to ThoughtWorks China WeChat subscription account
© 2021 ThoughtWorks, Inc.