TDD: Test-Driven Development

Write unbiased tests and “don’t waste your time coding”...

I recently read Test-Driven Development by Example by Kent Beck. This is one of the books that define Test-Driven Development (or TDD for shorter).

In summary, TDD is the concept of writing tests before writing the code itself. You write the smallest test, the test fails. You make the smallest update to code, the test succeeds. You refactor the code.

By writing tests first, developers can validate their understanding of the business requirements and ensure that every code is testable and the tests are unbiased.

Also, TDD increases the confidence in the code. There is less fear of changing a code when you know that the tests have your back. If a change breaks the code, an existing test will immediately fail.




In the first step of TDD, the test is the most important part that you write. Which means that while you're writing your test, you only add interfaces in the code but no implementations and you move on. You don't waste your time coding.

Once the test is written, then you go back to code and write the simplest solution that will make your test pass. And repeat that for the next tests...

Only at the end, you go back and refactor the code, removing duplication and cleaning up non-senses.

Paraphrasing the book: In TDD, you first solve the "that works" part of the problem and then you solve the "clean code" part, which is the opposite of architecture-driven development, where you first solve the "clean code" and then work around the designs trying to integrate them with the "that works" problem.


The book gives an example of:

	
//Test
public void testMultiplication() {
   Dollar five = new Dollar(5);
   five.times(2); // multiplies 5 * 2
   assertEquals(10, five.amount);
}
	
//Method implementation
public void times(int multiplier) {
   return 10;
} 
	

It looks dumb, but it does the job. The code does exactly what the test expects it to do. The author starts with a bogus implementation and gradually refactors the code to a real implementation. Once again, write the test first, implement the simplest solution in code to pass that test, refactor.


Another important point is when working on an existing code, if it is not [properly] tested, we should apply a similar concept. First write tests for that code, make sure you understand it and it's doing what it's supposed to do and then, apply your new changes. This way, you increase the confidence in the tests and in the code.


At the end of the day, TDD is an important topic to be considered. I can see it being used to write well defined APIs, service classes and such things. But in some cases, like to write GUIs, using TDD could be a little more challenging. Also, although automated tests can increase confidence for future changes in code, maintaining them can become difficult and, as the time goes by, the quality of new tests tend to drop. So, if the requirements are not very clear or for code that could potentially have multiple iterations, I don't think TDD would be the best option.


*Updated on 09/15/21: Added my opinion as conclusion.


References: