logo logo

TDD vs. BDD – Difference and Similarities

main post image

Product development always starts with planning. Planning helps the developers give direction and learn the motives in a better way. In the earlier days, we would gather the requirements, divide the development tasks and start the development process. As a next step, we would test the software, raise the issues and develop again.

Although that worked well in the past, the researches and increasing project complexities have given birth to two new concepts used in the planning phase today: TDD and BDD. TDD and BDD are the development processes that come during the start of the development and do the same job of shaping our development work. 

While TDD and BDD have been around for a while, people tend to confuse both the terms generally. Whenever someone asks, “What is the difference between TDD and BDD?”, the majority of the testers can’t solve this puzzle. Being the two most popular design techniques and foundations for test cases, I feel the need to declutter this situation so that you can answer that simple question in the future. In this post, we will solve the following riddles:

To understand the difference between the two entities, we must first understand them individually. At this point, I will not consider the involvement of BDD in the definition of TDD and vice versa to keep things simple. In the later section, when we are familiar with the concepts, it will help us compare both the mechanisms and build stronger foundations.

What is TDD?

TDD stands for Test Driven Development and the name speaks for itself here. When the development of the software is driven through the tests, we term this approach as TDD. In TDD, we start with the tests first which are based on the requirements or understanding of the software, and then move on to the development part. For example, if I know the software takes alphanumeric as a password, I can build a test around that before the code. Generally, the tests would fail because even though we know the functionality while writing the tests, the code has not been done in the same way. What do we do then? We refactor the code according to the tests until the test cases are passed and we are satisfied.

TDD process

To understand the test-driven development approach, in the example below, we will try to create a software that returns “True” when the number passed is divisible by 3.

As a rule, we will start with a very simple test to check if “1” passes the tests or not:

@Test
String Outcome = Func(1);
Assert.equals(“False”, Outcome);

In another file, I will write my code as follows:

String Func(int number){
   return “True”
}

The test case will fail because no matter what the number is, the Func() will always return “True”. This means we are not implementing the code correctly and is a call for refactoring. We refactor the code to “False”:

String Func(int number){
   return “False”
}

Now my test case will pass as the expected value is the real value. As a next step, I test with the number 2.

@Test
String Outcome = Func(2);
Assert.equals(“False”, Outcome);

This test case will pass too as the outcome is again “False”. At this point, we might think that this is the correct implementation of the software but the more test case you write, the better quality of the software will be written. Hence, I check for 3 now.

@Test
String Outcome = Func(3);
Assert.equals(“True”, Outcome);

This test case fails! Now we need to refactor the code. Maybe the value “True” is expected only for a number 3. So, I refactor my code accordingly as follows:

String Func(int number){
if(number == 3)
    return “True”;
return “False”
}

Now when I run all the test cases (1, 2 and 3), all my test case passes. I am on right track now. As a tester, I know that since the test case passed for 1 and 2, they would pass for any number except 3. So, I take 6 now as the input and write a test case as follows:

@Test
String Outcome = Func(6);
Assert.equals(“True”, Outcome);

Again, my test case fails as the number is not 3 and therefore the “Outcome” is “False”. I need to refactor my code again at this point. I make some new changes to my code as follows:

String Func(int number){
if(number % 3 == 0)
    return “True”;
return “False”
}

This will result in a successful test case on all the numbers. After repeated refactoring, we have achieved the function implementation according to the tests. Therefore, we call it a test-driven development. Sometimes, this is also called a “Red-Green” approach or “Red-Green” testing because the test fails (Red) and then passes (Green).

Benefits of using TDD

There are a lot of benefits of the TDD approach:

  • Better Quality Software: From the example above, it is understood that our repeated refactoring will result in a better quality of software. Since we are developing according to the tests, the requirements are already checked and satisfied.
  • Faster to Develop: A lot of the times, you would hear that TDD takes more time in development, sometimes up to 30% more. While that is actually true (not committing to any absolute numbers), it is just half of the story. When we find a bug at production and try to fix it, it costs us 100 times more than what would have been the cost at the time of requirement gathering. As a matter of fact, TDD reduces the production bugs density from 40% to almost 80%. This means our cost and time are being saved as the majority of the bugs are rectified before production. Therefore, if we take that into consideration, TDD actually helps in building a product faster, bringing down the time to almost half!!
  • Easy To Maintain: TDD helps in easy maintenance of the software as it reduces the production bugs up to 80%. When the troublemaker is out of the way and an already refactored code is sent to the production, there are very fewer reasons to worry about the maintenance.
  • Project Costs are Reduced: As explained in the second point about faster software development, a project’s cost increases to 100x when we need to fix the bugs in production. Since TDD reduces these bugs, we get a reduced project cost and a happy client.
  • Source of Motivation: The programmers are continuously executing the test cases in the TDD approach. After a few failures and refactoring, when all the test case passes, they are confident about the code they have written and feel motivated about their programming skills. The rewarding motivation helps in improving the programmer’s efficiency as these rewards are continuous in TDD.

What is BDD?

Another type of development strategy is Behavioral Driven Development. By now, I am sure you must have already guessed what BDD is in comparison to the TDD approach. BDD approach works towards the behavioural aspect of the development. In BDD, we start with defining the expected behaviour of the system and then write code accordingly. An example of behaviour can be, “if the customer is above 60 years of age, reduce the interest by 2%”.

 

Different Roles in Testing
Source: https://www.scaledagileframework.com/behavior-driven-development/

The strength of the BDD approach comes from the mode of communication used in it; plain simple English. Like English helps in bridging the gap between people in various parts of the world, BDD bridges the gap between non-technical and technical people working on the same project. BDD uses an informal approach and requires no technical knowledge in constructing the documentation. The process of BDD starts with a simple discussion between the client and the manager/analysts in order to understand the requirements and the software they need to develop. The next stage comes with documenting certain examples that satisfy the requirement for the client’s assurance as well as for the coder’s reference. The last stage is to code the requirements and test them with more tests and examples.

The following test represents the BDD approach for banking (or an ATM) software:

Money Transfer Changes Balance in Account

As an ATM cardholder
I can transfer money from Account
Transfer changes the balance

Given that I have $100 in my account
And my friend has $200 in his account
When I send $50 to my friend’s account
My balance reduces to $50
My friends balance increases to $250

The BDD language can be read, formulated, and updated by anyone from the technical or non-technical team. The greatest strength of BDD is that the client can read this language and understand if his requirements are correctly understood or not. Similarly, developers understand the requirements clearly too.

A BDD test comprises of three sections:

Context: This is the story or overview of the scenario. In the example above, “Money Transfer Changes Balance in Account” is the context.

Event: An event is a behaviour you want in the system. In the example above, the following is the event:

As an ATM cardholder
I can transfer money from Account
Transfer changes the balance

Outcome: The final section is the example section demonstrating the expected outcome of the event. In the above example, the following is the outcome:

Given that I have $100 in my account
And my friend has $200 in his account
When I send $50 to my friend’s account
My balance reduces to $50
My friends balance increases to $250

BDD is an excellent way to document the system behaviour and use it in place of unit tests because unit tests are very hard to perform when the system is completed or already exists. Covering a large audience under it, BDD tests are also a better choice than TDD as it allows a greater feedback loop (including the client) and other business and managerial employees. The only problem with BDD is that when something goes wrong in the tests, it is hard to locate what went wrong and at which location. This also increases the overall project development time.

There are a couple of popular tools to implement BDD, such as Cucumber, SpecFlow and Behave. In fact, TestProject is BDD testing ready, and has built-in BDD plugins for each of these BDD frameworks:

Benefits of using BDD

BDD brings loads of benefits with it, which makes it a popular choice in the organization. The most important benefits are summarized below:

  • Wider Involvement: Collaborations are always appreciated while writing the software, especially tests. With BDD, we not only collaborate between the testers and developers but also bring managers and analysts, and even clients into our team. The bigger collaboration helps in better communication between the teams and a good understanding of what to develop with what behaviour.
  • Clear Objectives: Simple English instructions make the objectives clear in the developer’s and tester’s mind which earlier would sometimes be twisted in multiple layers of communication.
  • Better Feedback loops: BDD involves more people collaborating on a project. Therefore, there are more eyes that can understand the tests and hence more fingers to type the feedback.
  • Lower Costs: Since the development is driven by the tests, the process reduces the chances of bugs in the later stages of the project (especially production) cutting down the overall cost of the project development.
  • Confident Team: A beneficial result of having clear objectives is that the team is confident in the overall process as they understand the requirement of the project clearly. Confidence helps in bringing the best out of them during the development.
  • Shift Left: BDD starts with the behavioural scenarios of the system which gives a direction to writing automation tests very early into the process. Early automation tests are directly responsible for lesser bugs in the later stages.
  • Ease out Automation/Testing: Automation testers get defined documentation with BDD. Therefore, it becomes very easy for them to write effective test cases.
  • Easy to implement on an existing system: Unlike unit tests, BDD tests can easily be written for an existing system. Actually, you can write BDD tests before, during, or after the development of the system as you wish.
  • Easy to update: Since BDD is written in a human-readable language i.e. English, they are very easy to update and communicate with other members.

Similarities between BDD and TDD

Even though the development in both methods is driven by different engines, they both possess the following similarities:

  • Shift Left: Both BDD and TDD facilitate the shift-left approach by starting the development process after writing the tests which is a very early stage into the development.
  • Reduce Costs: BDD and TDD reduce the overall project cost by limiting the number of production bugs up to 80%.
  • Early Bug Hunters: Both approaches are equally efficient in finding the bugs very early into the system which not only improves the quality of the software but ensures better maintenance.
  • Build Team Confidence: BDD and TDD provide tests even before the functionalities are developed. With constant refactoring of the code, green test cases increase the team’s confidence in being sure about the code from the start.
  • Quick Project Builds: Both approaches keep the objectives clear from the earlier stages of project development. This in turn eliminates bugs and speeds up the production cycles.
  • Iterative Process: Both BDD and TDD follow the iterative procedure of refactoring the code according to the test until they pass. This improves the quality of code.

Differences between TDD and BDD

Now that we understand the working and implementation of TDD and BDD, we can summarize the differences between them as follows:

Category TDD BDD
Language Technical (Code) English (Can be converted to DSL)
Test Understandability Tougher than BDD Easy
Participants Only technical teams Includes non-technical teams as well resulting in quick feedback.
Initiating Step Test Cases Behavioural Scenarios
Focus of Implementation  “How” to implement the functionality “What” functionality to implement
Tools JUnit, TestNG, NUnit etc. Cucumber, SpecFlow, Behave, MSpec, etc.
Bug Tracking Easier to track bugs as TDD shows which test failed and where Difficult to track as we only get to know what went wrong in the process
Defined Domain Functionality Behaviour

TDD or BDD – Which approach to go for?

TDD and BDD are both extremely important development techniques and are used very popularly today. But, that does not mean they can be used everywhere and anywhere we want. TDD and BDD can also prove to be expensive and ineffective when used in projects that do not require them. The below-given list underlines the correct process to use when you encounter the following scenarios:

  • One-Time Project: A lot of the projects are a “one-time” thing. You do not need to maintain them for long in the future. TDD is not a good approach in such cases. TDD increases the initial cost of the project which is compensated only if the project is being maintained for a long. BDD is a good approach to go here.
  • Pure-GUI Project: A project based on GUI is not advised to be started with the TDD approach. Although the team can use a thin layered TDD approach and not focusing too much on hard tests.
  • Scope of Project: TDD and BDD contradict each other in their functionality. While one is used for writing the test code, the other one focuses on the functionality of the system. Therefore, it is better to use TDD when the project involves non-behavioural aspects such as using third-party tools or API-rich projects. BDD on the other hand uses behavioural aspects into consideration, therefore, is best suited for projects which are user-action rich such as e-commerce websites. 
  • Team Familiarity: In some of the cases, you might find that your team is not familiar with the TDD approach which requires technical domain knowledge. As a next step, you can either train your team which will incur more costs and will increase the project delivery time or you can skip the TDD altogether. Analyzing the approaches and benefits discussed in this post, if you can work without TDD, you should go that way and use BDD instead.
  • Presence of an Existing System: When you are starting the work on an existing system, it is better to go with BDD as the behavioural cases are easy to understand and write. TDD will become a very complex task in such processes.

Conclusions

Alright! After a long discussion on two of the essential development approaches, we can now answer the question that we discussed at the start of this post, “What is the difference between TDD and BDD?”. Even though the question seems simple, a lot of the times I have found people being confused in both approaches, and the vague answers never seem to satisfy the questioner. 

I hope this post helps you decide which path to take while starting a project in the future. As a tip, I can say that sometimes, you can start with both of them if the requirements satisfy this approach. There is no harm in using both approaches or sometimes using none of them. Sometimes just unit tests and integration tests are enough for your project. There is no standardized “best” approach here and it depends completely on the project.

Apart from the points discussed here, if you have anything to add based on your experience, we welcome your suggestion in the comment section below. I hope this post helps you shape your testing and development approach in your next project! 🚀

Avatar

About the author

Harish Rajora

I am a computer science engineer with more than five years of experience in writing. I love development and reading books. Gaining and sharing knowledge is the best way to develop as a community and produce things that help people all over the world!

You can follow me on:

LinkedIn

Instagram

Twitter

Join TestProject Community

Get full access to the world's first cloud-based, open source friendly testing community. Enjoy TestProject's end-to-end test automation Platform, Forum, Blog and Docs - All for FREE.

Join Us Now  

Leave a Reply

popup image

E2E Test Automation Without Limitations

Create reliable codeless or coded tests from a secured hybrid cloud or fully offline. Debug fast and release at confidence with built-in test reports and a top-notch expert team supporting you at all times. 100% free.
Download TestProject 2.0 Free right arrow
FacebookLinkedInTwitterEmail