A weakness of the TDD method

tdd

This is in summary the TDD method:

  1. Write a test
  2. check if thes test fails
  3. write production code
  4. run test

I think that TDD as presented works only in ideal circumstances. I'll take a simple example:

Specification:
Write a program that calculates the square root of a number, the user must enter a number. If the number is negative, the program should display an error, and if the number is positive or zero the program should display the number whose square is the number entered, or for decimal number whose square is closest to the number entered.

Writing test

class SquareRootTest {

   private SquareRoot squareRoot;

   public void testNegativeNumber() {    
      assertException(squareRoot.execute(-5);   
   }

   public void testIntegerSquareRoot() {
      assertEqual(squareRoot.execute(9),3);
   }

   public void testDecimalSquareRoot() {
     assertEqual(squareRoot.execute(3),1.732);
   }
}

run failed test

writing production code:

class SquareRoot {

 public double execute(Number number) {
     if(number < 0) 
         throw exception;
     if(number < 1)
         return squareRootLessThanOne(number);
      else
         return squareRootGreaterThanOne(numner);
   }

//private methods....

}

this is when writing production code, I find that I have to deal with the numbers lower than one differently from those numbers greater than 1. So I need to update my tests to reflect this.

Updating test

class SquareRootTest {

   public void testNegativeNumber() {    
       assertException(squareRoot.execute(-5));   
   }

   public void testIntegerSquareRoot() {
       assertEqual(squareRoot.execute(9),3);
   }

   public void testDecimalSquareRoot() {
      assertEqual(squareRoot.execute(3),1.732);
   }

   public void testNumberLowerThanOne() {
      assertEqual(squareRoot.execute(0.04),0.200);
   }
}

If I had found a single algorithm to calculate the square root, I would not change my tests.

The TDD method focuses solely on tests from specifications, yet there are tests that are derived from the implementation, particularly all conditional instructions and all instructions controlled by loops should normally be tested. These tests case can not be detected at the time of specification.

My question: How does TDD will deal with this situation? or is effectivelly a weakness of the TDD?

Best Answer

The TDD method focuses solely on tests from specifications

No. It doesn't. TDD encourages adding tests based on your implementation. At each stage of your implementation you are looking for a test that will fail. You add that test, and then make it pass.

So in your case, when you found that numbers less than one have to be deal with differently, you'd start by adding a test for those numbers which failed your implementation. Then you'd add the less than one version.

Related Topic