Test-Driven Development compared to double-entry bookkeeping

What is so wrong with Test-Driven Development?

In What is so wrong with TDD on quora.com Robert Martin (Uncle Bob) compares programmers not using Test-Drive Development (TDD) to accountants not using double-entry bookkeeping. Ominously he concludes this comparison with: “Of course, if an accountant tried any of these excuses, they’d be fired or jailed. That day will come for programmers too. It’s just waiting on the right disaster.”

To me, what is so wrong with TDD? Nothing. TDD is a great tool to write production code and cover it completely by tests. What is wrong is people claiming TDD is the one and only way to write correct production code.

Why are production code and tests important?

Most businesses make their money using software. For software companies this is most clear. But imagine a factory producing goods. Without computers, orders have to be taken by phone or facsimile. And imagine order picking without support of a computer that tells you where the artiles are stored that need to be picked? Delivering orders would take more time and would be more error-prone, which in the end results in higher costs for the factory.

Thus businesses depend on correct production code delivered by software developers. It is the production code that creates value for the businesses.

However, if a software developer only produces production code without tests, then how can the businesses be confident that the production code stays correct in the future when the production code is updated? Since it is practically impossible to ()mathematically) proof production code correct, the next best thing we can do is cover it with automated tests.

To summarise: a software developer must deliver two things.

  1. Correct production code, because that is what creates value for businesses today
  2. Tests covering the production code, so that the production code stays correct in the future

In the end it does not matter how the correct production code and the tests are produced. In very small red-green-refactor cycles or by up-front reasoning about an algorithm, writing the algorithmand covering it with tests to keep it correct in the future.

Are tests only about keeping the production code correct in the future?

Tests not only serve the purpose of keeping production code correct. Here are my experiences with tests:

Wait, if you are so positive about tests, then what is so wrong with TDD?

Remember the goal I described above? Correct production code covered by tests? If a software developer is convinced about how to correctly implement an algorithm, then TDD is a good way to implement together with the tests. If the software developer first writes the correct production code and after that implements the tests, the result is the same.

There is more than one way to achieve the goal of correct production code covered by tests. The path followed by a software developer to reach the goal is not important.

My problem with TDD is that it will not help you implement an algorithm correctly in your production code if you do not understand the algorithm in the first place. I have seen examples of algorithms implemented with TDD that were incorrect (see Potter Kata Solution).

And even if an algorithm is implemented correctly, a limited set of tests do not convince me about the correctness. For example, Robert Martin implemented an algorithm to calculate the prime factors of an integer number. In the end he wrote just 7 tests, while there are infinitely many integer numbers. In Let tests drive or let Dijkstra derive? I show how to prove Martin’s algorithm is correct and explain why I don’t trust TDD in automatically resulting in correct production code.

Other techniques exist that give insight in what an algorithm actually does and in the end might even help you to mathematically proof an algorithm (see How invariants help writing loops).

What is so wrong with TDD? Nothing. TDD is a great tool to write production code and cover it completely by tests. What is wrong is people claiming TDD is the one and only way to write correct production code.

What is wrong with double-entry bookkeeping?

Back to the comparison of TDD to double-entry bookkeeping.

Double-entry bookkeeping has mainly two benefits over single-entry bookkeeping.

  1. It gives better insight in expenses and income than single-entry bookkeeping, thereby creating more insight for businesses
  2. It reduces the chance of a mistake adding up numbers is unnoticed.

Point 1 corresponds to correct production code; point 2 corresponds to tests. Point 2 was a real concern in the time double-entry bookkeeping was invented, centuries ago. In the age of computers we no longer worry about this anymore.

Can TDD protect us against the “right disaster”? I am afraid not.

Can double-entry bookkeeping protect us against the “right disaster”? At least it could not protect against the financial crisis of 2007 and the recession that followed.