When you look at any reference on Behavior Driven Development, you will find the usage of phrases such as “BDD is derived from TDD”, “BDD and TDD”. To know how BDD came into existence, why it is said to be derived from TDD and what is BDD and TDD, you have to have an understanding of TDD.
To start, let us get into the fundamentals of testing. The purpose of testing is to ensure that the system that is built is working as expected. Consider the following example.
Hence, by experience we have learnt that uncovering a defect as and when it is introduced and fixing it immediately would be cost effective. Therefore, there is a necessity of writing test cases at every stage of development and testing. This is what our traditional testing practices have taught us, which is often termed as Test-early.
This testing approach is termed as the Test-Last approach as testing is done after the completion of a stage.
The Test-Last approach was followed for quite some time in the software development projects. However, in reality, with this approach, as testing has to wait till the particular stage is completed, often it is overlooked because of −
The delays in the completion of the stage.
Tight time schedules.
Focus on delivery on time, skipping testing.
Further, in the Test-Last approach, Unit testing, that is supposed to be done by the developers is often skipped. The various reasons found are based on the mind-set of the developers −
They are developers and not testers.
Testing is the responsibility of the testers.
They are efficient in coding and their code would not have defects.
This results in −
Compromising on the quality of the product delivered.
Having the accountability for quality on testers only.
High-costs in fixing the defects, post delivery.
Inability to obtain customer satisfaction, which would also mean loss of repeat business, thus effecting credibility.
These factors called for a shift in paradigm, to focus on testing. The result was the Test-First approach.
The Test-First approach replaces the inside-out (write code and then test) to outside-in (write test and then code) way of development.
This approach is incorporated into the following software development methodologies (that are Agile also) −
eXtreme Programming (XP).
Test Driven Development (TDD).
In these methodologies, the developer designs and writes the Unit tests for a code module before writing a single line of the code module. The developer then creates the code module with the goal of passing the Unit test. Thus, these methodologies use Unit testing to drive the development.
The fundamental point to note that the goal is development based on testing.
Test Driven Development is used to develop the code guided by Unit tests.
Step 1 − Consider a code module that is to be written.
Step 2 − Write a test
Step 3 − Run the test.
The test fails, as the code is still not written. Hence, Step 2 is usually referred to as write a test to fail.
Step 4 − Write minimum code possible to pass the test.
Step 5 − Run all the tests to ensure that they all still pass. Unit tests are automated to facilitate this step.
Step 6 − Refactor.
Step 7 − Repeat Step 1 to Step 6 for the next code module.
Each cycle should be very short, and a typical hour should contain many cycles.
This is also popularly known as the Red-Green-Refactor cycle, where −
Red − Writing a test that fails.
Green − Writing code to pass the test.
Refactor − Remove duplication and improve the code to the acceptable standards.
The steps of a TDD process are illustrated below.
The benefits or advantages of Test Driven Development are −
The developer needs to understand first, what the desired result should be and how to test it before creating the code.
The code for a component is finished only when the test passes and the code is refactored. This ensures testing and refactoring before the developer moves on to the next test.
As the suite of Unit tests is run after each refactoring, feedback that each component is still working is constant.
The Unit tests act as living documentation that is always up to the data.
If a defect is found, the developer creates a test to reveal that defect and then modify the code so that the test passes and the defect is fixed. This reduces the debugging time. All the other tests are also run and when they pass, it ensures that the existing functionality is not broken
The developer can make design decisions and refactor at any time and the running of the tests ensures that the system is still working. This makes the software maintainable.
The developer has the confidence to make any change since if the change impacts any existing functionality, the same is revealed by running the tests and the defects can be fixed immediately.
On each successive test run, all the previous defect fixes are also verified and the repetition of same defect is reduced.
As most of the testing is done during the development itself, the testing before delivery is shortened.
The starting point is User Stories, describing the behavior of the system. Hence, the developers often face the following questions −
When to test?
What to test?
How to know if a specification is met?
Does the code deliver business value?
The following misconceptions exist in the industry and need clarifications.
Misconception | Clarification |
---|---|
TDD is all about testing and test automation. | TDD is a development methodology using Test-First approach. |
TDD does not involve any design. | TDD includes critical analysis and design based on the requirements. The design emerges during development. |
TDD is only at Unit level. | TDD can be used at the integration and system levels. |
TDD cannot be used by traditional testing projects. | TDD became popular with Extreme Programming and is being used in other Agile methodologies. However, it can be used in traditional testing projects as well. |
TDD is a tool. | TDD is a development methodology, and after every new Unit Test passes, it is added to the Automation Test Suite as all the tests need to be run whenever a new code is added or existing code is modified and also after every refactoring. Thus, Test Automation Tools supporting TDD facilitate this process. |
TDD means handing Acceptance tests to the developers. | TDD does not mean handing Acceptance Tests to the developers. |
Acceptance Test Driven Development (ATDD) defines Acceptance Criteria and Acceptance Tests during the creation of User Stories, early in development. ATDD focuses on the communication and common understanding among the customers, developers and the testers.
The Key practices in ATDD are as follows −
Discuss real-world scenarios to build a shared understanding of the domain.
Use those scenarios to arrive at acceptance criteria.
Automate Acceptance tests.
Focus the development on those tests.
Use the tests as a live specification to facilitate change.
The benefits of using ATDD are as follows −
Requirements are unambiguous and without functional gaps.
Others understand the special cases that the developers foresee.
The Acceptance tests guide the development.
According to Dan North, programmers normally face the following problems while performing Test Driven Development −
Where to start
What to test and what not to test
How much to test in one go
What to call their tests
How to understand why a test fails
The solution to all these problems is Behavior Driven Development. It has evolved out of the established agile practices and is designed to make them more accessible and effective for teams, new to agile software delivery. Over time, BDD has grown to encompass the wider picture of agile analysis and automated acceptance testing.
The main difference between TDD and BDD is that −
TDD describes how the software works.
On the other hand, BDD −
Describes how the end user uses the software.
Fosters collaboration and communication.
Emphasizes on examples of behavior of the System.
Aims at the executable specifications derived from the examples