TDD vs BDD: Understanding the significant differences

bdd tdd

In the new era of agile development, new software changes are introduced continuously. In parallel with development, testing has emerged as a big factor for software companies. All continuous changes may introduce new bugs or even brake the application once going live. The right development approach needs to be considered. There is a big talk about which method should you use. In this post, we are going to talk about TDD vs BDD approach that almost every organization’s development is based on.

What is TDD?

TDD or Test-Driven Development is a software development approach where we initially write a test case for specific functionality and then write the code for that test case. It is a development technique but can also be used for the testing automation process. Although it can take more time for development, this approach results in very few bugs detected during implementation. The goal for TDD is to achieve at least 85-90% coverage.

TDD Workflow

tdd bdd
TDD

TDD workflow includes the following steps:

  1. Write a test case for the functionality and automate it
  2. Execute the test case against the first developed iteration
  3. If the test fails, develop the code to meet the test expected outcome
  4. Execute the test again against the updated code
  5. Refactor the code to be more structured and more readable
  6. Repeat all steps from 1-5

Example of TDD

Let’s take a simple TDD JavaScript/Jasmine example.

// Test code
import car from './car'

describe('Car view page', () => {                                                                       
  it('List a car', ( ) => {                                                          
    expect(car()).toEqual('Bentley')                                                                             
  })
});
// Development code

export default function car() {
}

The first two steps of the development iteration are done. We created a test and development code. The initial test says that we are expecting a car named Bentley from the application to be returned and to assert the expected result that we are setting. The application at this moment returns undefined so the test fails. We need to add some return statement in the development code in order to satisfy the test.

// Development code
export default function car() {
   return ['Bentley']
}

The initial development returns a string Bentley so the first phase is passed. If add another assertion like:

var getCarsList = car();
expect(getCarsList[1]).toEqual('BMW')                                                                             

We need to add another car string in the return development statement

export default function car() {
  return ['Bentley', 'BMW']
}

We can add as many assertions as we want in the test code and in parallel, develop the code to fully cover the functionality.

TDD Pros and Cons

Couple of pros and cons by using TDD approach includes:

Pros

  • Enforces you to write small tests, e.g. making your code more structured and modular
  • Easier code equals easier refactoring
  • Helps developers really understand their code
  • Small development errors are detected immediately

Cons

  • It slows down the development process since it has to have a good set of tests first
  • Tests are not so easy to write since they need to be created before the actual implementation
  • Hard to start following this approach if you didn’t work this way
  • Refactoring development requires early test code refactoring

What is BDD?

BDD or Behavior-Driven development is another software development approach derived from TDD but eliminates all the shortfalls of TDD. Here, instead of writing a test case, we write behavior. It sounds a bit confusing but in general it is really straightforward. Once the behavior is written, the following code is developed to fulfill the expected behavior of the application. It is considered a best practice when it comes to automated testing.

BDD Workflow

BDD

BDD workflow includes the following steps:

  • Write the behaviour of the functionality in a simple English language
  • Automated the already written behaviour in English by writing test scripts
  • The functionality is then starting with the implementation
  • Execute the behaviour and check if it fails or succeeds. If it fails, fix the errors to meet the application behaviour
  • Refactor the code to be more structured and more readable
  • Repeat all steps from 1-5

Example of BDD

The best way to explain this approach is to use the BDD tool for automation testing called Cucumber (it is compatible with tools like Rest Assured and Protractor) where we can write some behavior using Gherkin language. Let’s take a simple BDD Cucumber example.

We have scenarios where we need to navigate to a login page, enter our username and our password, and click the login button. Then we verify that we are successfully logged in. Using Gherkin language it will look something like this:

Scenario: Login functionality
Given I navigate to the login page 
When I enter "username" username
And I enter "Password" password
And I click on the "Login" button
Then I can see that I'm susccessfuly logged in

The keyword Scenario explains the actual test that we want to cover, the Given keyword is the preconditions that must be met if we want to continue with our test. The When and And keywords are the actions that we are making in our test and the Then keyword is the outcome that we want to expect based on our actions. This is the first step in this approach.

The next step is to write the code

@Given("^I navigate to the login page $")
public void loginPage(){
   loginPage.navigateToLoginPage();
}

@When("^I enter \"([^\"]*)\" username$")
public void enterUsername(String username) {
   loginPage.enterUserName(username);
}

@When("^I enter \"([^\"]*)\" password$")
public void enterPassword(String password) {
   loginPage.enterPassword(password);
}

@When("^I click on the \"([^\"]*)\" button$")
public void clickSubmitButton() {
   loginPage.clickSubmit();        
}

@Then("^I can see that I'm susccessfuly logged in$")
public void verifyLoginprocess() {
   expect(loginPage.isLoginSuccssful()).toBe(true);
}

Based on this test where it looks pretty simple, a development code needs to be implemented. Run the behavior and verify if it is successful. If it is then, all you need to do is refactor the dev code to your choice and looks and repeat this process with new behavior.

BDD Pros and Cons

Pros and cons by using BDD approach includes:

Pros

  • BDD provides so to say living documentation that any member of the team can understand regardless of their level of technical expertise
  • Encourage the use of Domain-specific language
  • It involves the tester early in the project life-cycle
  • Enforce creating automated tests during development
  • Refactoring of the code is less risky since we already have automated tests in place

Cons

  • IT requires a big-time effort to create the feature files and scenarios especially for large applications
  • Involvement of every member of the team per discipline is required which can become a complex discussion regarding what scenarios should we cover and what not
  • Maintaining feature files where the behavior is written is also time effort and it needs to constantly be in sync with the development
  • More time for automating code which will demand more resources in the organization

TDD vs BDD: Differences

So, we talked about what is TDD and BDD, their workflows, examples and their advantages and disadvantages. Now, let see why they differ and why there is a big talk of what approach is better and when to use it.

TDDBDD
Writing a test case in a programming languageWriting a behavior in a simple English language
Collaboration between developersCollaboration between all members of the team
Focuses on how the feature is developedFocuses on how the behavior of the applications needs to be developed
Programming knowledge required for those who want to understand the testsTests in BDD can be understood by any person with no programming knowledge at all
Best tools for TDD: JUnit, TestNGBest tools for BDD: Cucumber, SPecFlow
In TDD we are interested in executing the tests in a right wayIn BDD we are interested in the output of the tests to meet the expectations
Differences between TDD vs BDD

The Bottom Line

There is no choosing what approach you will take since they are different in terms of what we are trying to achieve. TDD minimizes the potentials bugs in production and ensures stable application release. BDD follows the same metrics as TDD but it is more structured/readable in terms of how the information is represented to the user and its focus is solely ensuring the overall behavior of the application is met and the end-user is satisfied.


Share this post

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.