I was first introduced to the BDD framework in April 2016. Thought it was brilliant and been have using the framework in my projects ever since. It is a great way to design a piece of software “on paper” as it were. Then code against this design to make sure you are building “the right thing”.
Sorry if my blog headline is a little misleading. I don’t believe TDD is dead completely. There is a place for TDD when I’m writing new code. However, the majority of my testing is performed using BDD tests.
Since July 2019 I have been working on a side project called Outflash. I have used the BDD framework throughout this project. Helping me design the solution as I would like. And to make sure I have covered every eventuality.
What Is BDD?
BDD stands for Behavioural Driven Development or Business Driven Development. It is a software development approach that has evolved from TDD (Test Driven Development). It differs from TDD as each test is written in a human readable format. This improves communication between tech teams, non-tech teams and stakeholders.
This helps people who aren’t particular technical to get involved in the design process.
A business may employ people who have a lot of expertise and understand a particular market. However, they may not have the technical background to communicate what they need a piece of software to do. BDD bridges that gap by using plain English.
BDD writing sessions produce test cases that both technical and non-technical people can refer to and that they understand.
In both TDD and BDD development approaches, tests are written before any code is writen. However, BDD tests are more user or process focused and based on the system’s behaviour.
How BDD Is Structured
When writing a BDD test, more commonly know as a scenario. A test case (scenario) is normally structured is the following format.
Given a certain scenario
When an action takes place
Then this should be the outcome.
For example, this would be the scenario for implementing a login screen for an new website application.
Given the User has not entered any data on the login screen
When they click the login button
Then proper validation messages should be show.
This is a very basic example. Hopefully, showing how BDD test files are structured. Later on in this post I will give you a more detailed, real world example.
Benefits of Using The BDD Framework
With the BDD framework, you aren’t defining a ‘test’ (a specific outcome of a piece of code). You are defining ‘behaviour’. By using the BDD framework, not only can you test that blocks of code work as expected. You also test that different blocks of code works together correctly, to produce expected outcomes.
Using BDD improves the communication between developers, testers, product owners and other members of a business. Because test files are written in a human readable format (Given, When, Then) this makes it easier for people to understand. Helping reach a wider audience.
Another benefit is the learning curve for developers, testers and other team members is a lot shorter. Someone can get up and running understanding what needs to be achieved and how to structure a process in a very short space of time.
With a BDD test, the acceptance criteria for how something should work and be tested is defined before one line of code is written. This prevent software teams from building and testing the wrong thing due to lack of understanding.
Using BDD also speeds up the development process. This sounds counter intuitive as it seems you are writing twice the amount of code that you need to reach an outcome. From my experience, writing the BDD scenarios first helps you reduce the amount of code you write to make something work, fulling the test scenario. BDD also helps developers to stick to SOLID and clean code principles.
I have also found that using BDD makes it easier to add more functionality and new features to my code. To implement improvements, it’s a case of adding more Given When Then’s to existing or new scenarios to spec out what improvements or feature you want to add.
A Real World Example
If you have tinkered with any new programming language you will be familiar with implementing the old “Hello World” example. Personally, I don’t like Hello World as a starting point. I understand you need low entry barriers. However, I think it doesn’t show the power of programming.
Hopefully the following real world example will show the power of BDD and software. Without going into too much technical detail.
I have already mentioned the project I have been working on since July 2019. My side hustle is called Outflash. The #1 Email Enhancement Add-in For Outlook.com. I won’t go into too much detail of what it is and how it works. The main goal of the email enhancement add-in is to allow users to send mass emails using Outlook.
As part of the solution I needed a processor to send emails on a users behalf. To make sure it worked as I wanted and covered all the steps I needed. I used a BDD framework called SpecFlow.
Using the framework. I documented the scenario of successfully sending an email using Given When Then’s. As well as making sure I worked out what to do if something went wrong during the processing.
Initial Email Scenario Outline
Below is the first version of the BDD scenario I put together for the email processor. To make sure my code could retrieve and send an email on a users behalf.
Scenario: Email in queue is sent to a valid contact Given A new email processor And The following emails are in the queue | FromEmailAddress | ToEmailAddress | DraftId | | firstname.lastname@example.org | email@example.com | draftId | And The following user is retrieved | Firstname | Lastname | EmailAddress | | Phil | Test | firstname.lastname@example.org | And A draft email is returned And A valid contact is returned | GivenName | Surname | CompanyName | | PHH | Digital | PHH Digital | When The queued emails are sent Then The retrieve emails was called '1' times And The retrieve user was called '1' times And The retrieve message was called '1' times And The retrieve contact was called '1' times And The message was sent And Update email was called '1' times
As you can see I have put down in plain English what I expect the processor to do. Easy to understand I think you would agree?
This structure also benefited me as I had a clear focus of I wanted to build. How it all fits together. What should happen, when. Clearly defining the expected outcome from processing a queued email.
One thing I want to mention is that I haven’t completely discarded the TDD framework. I still use test driven development to make sure that key things like constructors receive expected parameters. Or to test key functionality that is critical to the inner working of the software work as expected.
Updates and Improvements
I just want to quickly show you how easy it is to add new functionality into the BDD scenario and code against it.
Scenario: Email in queue is sent to a valid contact Given A new email processor And The following emails are in the queue | FromEmailAddress | ToEmailAddress | DraftId | | email@example.com | firstname.lastname@example.org | draftId | And The following user is retrieved | Firstname | Lastname | EmailAddress | | Phil | Test | email@example.com | And A draft email is returned And A valid contact is returned | GivenName | Surname | CompanyName | | PHH | Digital | PHH Digital | When The queued emails are sent Then The retrieve emails was called '1' times And The retrieve user was called '1' times And The retrieve message was called '1' times And The retrieve contact was called '1' times And The replace placeholders was called '2' times And The unsubscribe placeholder was called And The append footer was called And The message was sent And Update email was called '1' times
In the updated scenario I added 3 steps, highlighted in bold and italics. I wanted to be able to add place holders in an email template and replace them with information from an Outlook contact record.
When I then ran the test scenario, it failed due to the new lines not being satisfied. It took me no time at all to code this functionality and get it deployed to production.
There you have it. A quick overview of BDD using a real world example of how the framework can be used in your projects..
Thanks for reading BDD Is The New King. TDD is dead. Long live BDD. I would like to hear your thoughts. Phil