Disclaimer to start with: the title of this blog is a bit of a misnomer. The reason for intentionally titling this blog incorrectly is to clarify and hopefully make readers/users understand why “BDD Unit Testing” is inherently contradictory. The term Unit Testing relates to test-driven development (TDD), which is different from behavior-driven development (BDD). Though both TDD and BDD take the “test first” approach before moving on to development, there are quite a few differences between them. One of my other blogs explains the differences between BDD and TDD.
In this blog, we will see what BDD and Unit Testing are, why you should consider BDD and its benefits, and how you could automate BDDs in minutes and without writing any code. We will also see how you can implement BDD and TDD in a project and improve the overall quality of the product.
Why Behavior-Driven Development?
The hardest single part of building a software system is deciding precisely what to build.
– Frederick P. Brooks, The Mythical Man-Month: Essays on Software Engineering
The Mythical Man-Month was first published in 1975. Even after 46 years, this statement holds true. Though the programming standards, the software tools to help to build the software, and project management practices have improved over the years, the standard for defining “what to build” is still understood in vague terms. It’s vague because it is defined in natural language, potentially leading to several (mis)interpretations. According to Oxford Dictionary about 500 commonly used words in English have an average 23 meanings. Not just words, but the phrases and sentences as well can be interpreted in more than one way.
When the product owner or the BA provides requirements, they might not even be aware that the requirements are ambiguous to the team. To an extent, this problem is addressed by the team collaborating with the product owner. However, this would resolve only those ambiguities the team members pose as questions.
If a team member doesn’t pose a misunderstanding of the requirements as a question, mis-interpretation can come into play. This is a much more serious problem. In this scenario, the team or the BA/Product owner wouldn’t realize it until the functionality is built because of a lack of collaboration.
Many might think this is less of an issue in Agile software development, and they are certainly right. Agile does address this problem better compared to waterfall; however, when functionalities are time and time again built incorrectly, the time taken to recorrect them will finally end up costing a lot, and the project timeline would be impacted. Let’s look at few Examples and see how requirements could be mis-interpreted.
Example 1 – How do you brush your teeth?
Let’s take a look at a simple example that we use every day: brushing our teeth. Let’s try to write that process in simple language:
- Take the brush out
- Wet the brush
- Put on the toothpaste
- Hold your brush at a 45-degree angle against your gumline
- Gently brush from where the tooth and gum meet to the chewing surface
So, how do you think someone who has never brushed or has never seen someone brushing in their life would interpret these steps? May be something like below:
It would be difficult and time consuming to write the right description for someone who has never brushed their teeth before or has never have seen someone brushing their teeth. So how do you get someone to brush their teeth correctly? The simple answer is by showing them how to brush their teeth—or in other words, by using an example. And one of the salient features of BDD is writing requirements as examples.
Example 2 – Weather
Let’s take another simple example, one that’s more related to software development. If there is a requirement to develop a weather app, then the description of the requirement would be something like:
The website shall show the weather for the next 24 hours.
However simple the above story might be, it can lead to mis-interpretation. Should the current weather be shown for the next 24 hours or should the website show the projected weather for the forthcoming 24 hours? Moreover, different members of the team can understand the above story differently.
What is BDD?
It is a general mis-conception that BDD is used for Test Automation. Though Test Automation is a great benefit of BDD, the main purpose of BDDs is to remove any ambiguities or possibility of mis-interpretation of the requirements and keep all team members—technical or non-technical—on the same page.
BDD in essence is composed of three parts:
- Collaboration through examples
- Deriving scenarios in ubiquitous language
- Automate scenarios
Let’s look at each of these steps in detail.
Collaboration through Examples
As mentioned above, the most difficult part of software development is understanding what to build. The main reason is that usually the person who provides details about what to build is not the one who builds the software. And the requirements to build the software are provided in natural language, which can be interpreted in different ways and entirely depends on the reader.
Let’s look at a simple story, as explained in one of the articles by the originator of BDD, Dan North:
Simple User Story
As an account holder, I want to withdraw cash from an ATM so that I can get money when the bank is closed.
When a requirement like this is given, the team members involved in developing this requirement, primarily the three amigos, have to collaborate and derive different scenarios with real world examples related to their domain. So, for the above scenario, the team would derive scenarios like:
Scenario 1: Account has sufficient funds
Given the account balance is \$100
Scenario 2: Account has insufficient funds
Given the account balance is \$10
Scenario 3: Card has been declined and Account holder should not be allowed withdraw money
Scenario 4: The ATM has insufficient funds
As you can see, the above scenarios clearly explain to the entire team the different scenarios that need to be considered when developing the software. All the team members–the business person, the developer, and the tester–are all on the same page and know exactly the scenarios businesses expect the software to deliver.
Many teams do some kind of collaboration, but in order effectively use BDD and to have a strong collaboration, it helps greatly to follow a process or a proven technique.
BDD collaboration Technique
I’ve been using OOPSI in many projects and it has dramatically improved the efficiency of the collaboration and unearthed several scenarios that otherwise wouldn’t have been possible and kept all the team members engaged and on the same page.
OOPSI was introduced by Jenny Martin and Pete Buckney. OOPSI stands for:
O – Outcome
O – Output
P – Process
S – Scenario
I – Input
You can read more about OOPSI in this excellent article by Jenny Martin. By using a technique like this to derive scenarios, waste is reduced up front: the team will understand and document what is required and what is not.
Deriving Scenarios through Ubiquitous Language
When the team agrees on the scenarios, next in the process is to write steps required to fulfill what is agreed upon in the scenario. These steps are written in a common language that is understood by both technical and non-technical members of the team. The steps are written in a language called Gherkin. Since Gherkin uses plain language, the steps written using this language can be understood by anyone.
Let’s look at an example of how these steps are typically written for one of the scenarios we derived in the earlier section (again taking the scenario explained in Dan North’s article):
Scenario 1: Account has sufficient funds
Given the account balance is \$100
And the card is valid
And the machine contains enough money
When the Account Holder requests \$20
Then the ATM should dispense \$20
And the account balance should be \$80
And the card should be returned
As you can see, the steps to achieve the scenario are very easy to understand, regardless of one’s technical know-how. This is quite a critical point, as it clearly explains how the software will be built in a real world example and keeps the entire team on the same page.
So, when the developer implements a solution based on the derived scenario and steps, how does one make sure the agreed steps are implemented correctly? That’s where automation testing comes into picture.
Once the scenario and the required steps are defined, the QA team should automate the testing of the scenario(s) by writing test script for each step. Though manual testing is an option, you miss out on a huge advantage of rolling out BDDs: automation. Some teams consider manual testing or partial manual testing (i.e., automating only core features), as automating through scripts or using popular open-source software like Cucumber (which again requires scripts/code to automate) might take considerable time, and it might not be easy to justify to businesses. Maintaining the automation code also takes considerable time, resources, and funds. Thus, we built NoCodeBDD, which allows you to automate BDD scenarios in minutes, without having to write any code.
The following video shows how you could use NoCodeBDD to automate the scenario we derived above. As you can see, automating using NoCodeBDD doesn’t require any coding and can be done in minutes. NoCodeBDD supports UI, REST, Relational Database, and MQ automation.
Black Box Testing
It is quite important to understand that BDD testing is Black Box testing. As you saw in the above video, you don’t need to know anything about the code in order to test the application via BDD. This is useful because QA doesn’t need to know the implementation details and all they have to do is focus on the business scenarios.
Even if you use an open-source tool like Cucumber, in which you need to write your code to automate test scenarios, you are still performing Black Box testing, as the code that you write doesn’t have to know anything about the implementation details of the software. But QA has to spend a considerable amount of time automating the test code instead of spending time on testing and use the coding prowess.
Since BDD is Black Box testing, it comes with all the benefits, some of which are given below:
- Tests are performed from an end user point of view, and QA doesn’t prejudice / isn’t influenced by the implementation details.
- Even if the implementation code changes, the test scripts don’t have to change as long as the specification or the design aspects don’t change.
- QA doesn’t have to know the implementation details.
- Black Box testing can be demonstrated easily to end users, as it reflects their expectations. This is even more apt with BDD, as the tests are written in plain language the end user can easily understand.
What is Unit Testing?
Unit testing is implemented as part of TDD. A unit test is an automated piece of code invoked to check whether the code is implemented as expected.
Many misinterpret unit testing as TDD. However, TDD is a software development process in which the developer writes a test for a given function, then writes enough functional code just for the test scenarios to pass. Then, if required, the developer refactors the code to make it better.
If you are interested in knowing more about TDD, as well as the differences between TDD and BDD, check out my TDD vs BDD article.
Does BDD replace Unit Testing?
BDD doesn’t replace unit testing or TDD. The two are merely used for different purposes. As we saw in previous sections, BDD should mainly be used to get the team on the same page and make the requirements clearer. It should be considered a requirement specification that can be executed. Also, BDD can be used to test the behavior of the entire application and can depict a user journey. TDD is used by developers to test a unit of their work by writing unit tests. In order to implement TDD, the developer needs to know the underlying code.
Using both BDD and TDD together improves the quality of the software and reduces time to market. In a development process, BDD starts before TDD. BDD should be the first process in your software development and should start as soon as the user story/requirement is provided. So how do you use BDD and TDD together?
Using BDD and TDD together?
When the team is ready to start implementing the user story, the first step is to collaborate between all technical and non-technical members and derive the scenarios and the steps. Once the scenarios are derived, defined, and agreed upon among team members, the developer should use the scenarios and steps to implement a solution, and the QA uses the scenario to build the automation scripts.
As mentioned above, TDD starts before the developer starts implementing the solution. Before the developer writes the actual code, they write unit tests, evaluating different scenarios of what the code executes. The unit test focuses on the functionality the developer will be implementing and not the behavior of the entire application or the user journey.
For an example, in the scenario that we defined above:
Scenario 1: Account has sufficient funds Given the account balance is \$100 And the card is valid And the machine contains enough money When the Account Holder requests \$20 Then the ATM should dispense \$20 And the account balance should be \$80 And the card should be returned
The developer would be writing Unit Test for a functionality that checks the account balance as that would be one of the functionality he would be implementing. This is shown in the video below:
As we’ve learned, “BDD unit testing” is oxymoronic. Since BDD and TDD take the test-first approach and sound similar, it is a common misconception that BDD is an extension of TDD. However, as we have seen in this article, BDD should be used mainly to iron out any ambiguities in the requirements and establish a specification that can be run through automated scripts. This specification can be understood by both technical and non-technical members of the team. However, unit testing belongs to TDD, and is written by the developers alone to test a unit of the code. The tests written are understood by technical persons. However, using both BDD and TDD improves software quality and speeds up delivery in the long run. As we have shown in this blog, Rolling out BDDs and Automating them will take only minutes and without any code. The basic version of the NoCodeBDD product is Free and you can download it from http://www.nocodebdd.com/download and start rolling out BDDs in minutes.
Jerome Josephraj is the Founder and CTO of NoCodeBDD. He has more than 20 years of experience in Software Development and have been rolling out Behavior Driven Development for large projects in United Kingdom. He has a strong Java Development Background and have been working as a Technical Consultant. In one of his recent large enterprise projects, he has successfully rolled out Behavior Driven Development consisting of more than 1000 scenarios. He was also the Founder of http://www.campusinteraction.com, a student analytics portal, which was later bought by Preludesys. Based on the previous start-up experience and a strong Behavior Driven Development experience, he founded NoCodeBDD to improve efficiency of rolling out Behavior Driven Development by 10x.