In this article, we will look at the basics of Test-Driven Development (TDD) and look at one example of how to write unit test using TDD concept.

Extreme programming is one of the Agile Development Processes and TDD is one of the core practices of extreme programming.

Test Driven Development also referred as ‘Test First Development’. In traditional unit testing, we write code for the requirements given & then write unit test cases but in TDD we write unit test & make it fail to create code that fulfil the requirements. This new software development approach enables code maintenance easier especially avoiding duplicate code and bug-free as we start looking at the scenarios for the functionally and making sure it all passes.

In this test first approach, test drives the creation of software and design of the program. We do write the test cases in an iteration until the test passes.

Steps for TDD:

  • Write new test case that satisfy functional scenario
  • Execute the test case & it will fail as piece of code functionality is not written
  • Refactor the code that fulfils the test criteria
  • Re-execute the test case again
  • Repeat until all the scenarios are covered

It is illustrated in the below diagram.

Let’s look at one example below.

Requirement is to create microservices API that accepts the operator & two integer inputs as parameters to perform add, subtract, multiply operation. (Am using Spring Boot Java application to create the microservices for this example).

Below are the few scenarios to fulfil the requirement

  • Ability to perform only add, subtract, multiply operation only
  • Ability to return default value when other operators are passed as parameter

Let’s follow the TDD flow and start adding the test.

Step 1:

Create test for checking “+” operator.

@Test
//Perform test to check whether the operations of Add working
void CalculateTest_TestAddOperations_IsTrue (){
   var calculate_obj = new Calculation();
   int result = calculate_obj.Calculate(“+”,1,2);
   Assert.assertEquals(result,3);
}

Included class named ‘Calculation’ and method ‘Calculate’ .

Step 2:

By running the test with this, it returns failure message. Its expected as we didn’t write the code to do add operation yet.

Step 3:

Refactor code to include the functionality now of addition now.

Step 4:

Rerun the same test again and it will be pass right now.

Step 5:

Repeat the same steps till you complete the functionality and all test are passed.

I have included below test cases

@Test
   //Perform test to check whether the operations of Sub working
void CalculateTest_TestSubOperations_IsTrue(){
   var calculate_obj = new Calculation();
   int result = calculate_obj.Calculate("-",1,2);
   Assert.assertEquals(result,-1);
}
@Test
   //Perform test to check whether the operations of Multiply working
void CalculateTest_TestMultiplyOperations_IsTrue(){
   var calculate_obj = new Calculation();
   int result = calculate_obj.Calculate("*",1,2);
   Assert.assertEquals(result,2);
}
@Test
   //Perform test to check whether other operators returns default value
void CalculateTest_TestAnyOperations_IsTrue() {
   var calculate_obj = new Calculation();
   int result = calculate_obj.Calculate("/",1,2);
   Assert.assertEquals(result,0);
}

Final code below

@RestController
public class Calculation {
    int result =0 ;
    @GetMapping("/Calculate/{operator}/{first}/{second}")
    public int Calculate(@PathVariable String operator, @PathVariable int first, @PathVariable int second)
    {
        if (operator.contentEquals("+"))
            result = first + second;
        else if (operator.contentEquals("-"))
            result = first - second;
        else if (operator.contentEquals("*"))
            result = first * second;
        return result;
    }
}

Have changed the “==” to “contentEquals” to support running from URL.

Running from URL shows the output below

This is how we should approach writing test then development. But what’s the advantage of doing this?

Advantages of TDD:

  • Maintenance of code is easier

. Avoid duplication of code as we write code that’s only required

. Easier code refactoring

  • Test coverage is high
  • It documents the code as test tells us what the code does and way the interface to be used
  • Less debugging as it identifies bug earlier
  • Follow modular design: we write test & code for small features and clearly structured.

Disadvantages of TDD:

  • It’s a very slow process as we write test then code
  • One has to understand the clear functional requirements to write test

Hope this article will be helpful.