Now that the dust has settled, and a sufficient number of the followers of the Test-Driven Development (TDD) religion have moved onto the next fad, I can crawl out of hiding and voice my objections. I have always been against TDD, as I felt it was a literally backwards approach to coding, which had glaring flaws.

Test-Driven Development is the concept that unit tests or automated tests should be the starting point of a project. You know what results you want. You write tests that should produce those results. Then, you flesh out the code to make the tests pass.

It was a novel idea around 10 years ago, and it does come with some benefits. First, unit tests or automated tests are very much part of the coding process, as opposed to being an often neglected afterthought. Automated tests are vital for verifying functionality and performing regression testing whenever changes are made. Second, it provides a relatively easy starting point to beginning a project. That's about it.

Now, while I agree that automated tests should be an integral part of a project, and that anything that makes a project easier to start is better than inaction, I think that proponents of TDD push that approach to a impractical level, which starts to produce some major issues, both in the short-term, and more concerningly, in the long-term.

First, conceptually, a project that starts from the tests, and builds from that is putting the cart before the horse. Without an overall design, or thoroughly thinking through the architecture of a project, the end result is often times a complete mess - brittle to change and a nightmare to maintain. Making the tests pass should be a minimum requirement, and not the goal of a project. Tests cannot replace proper design and forethought.

Second, the elephant in the room that everyone seems to ignore is that passing tests do not guarantee the code is behaving correctly. Evangelists of TDD trust too much in automated tests, believing them to be the absolute truth in flawless code. Unfortunately, automated tests are only as thorough as they are made to be, and while they can be quite thorough, in my experience, they are usually superficial, only covering the most basic use cases, the cause of which leads to the next point.

Automated tests require effort (time and resources) to create. A project with a robust set of tests may require just as much effort, if not more, than the intended functionality of the project. Once a robust set of tests is created, that introduces two more side effects. The more tests there are or the more complicated the tests are, the more time they take to run, and whenever the intended behavior of the code needs to change, the more effort is required to refactor all those tests. For the automated tests to be the starting point of a project would mean that often times, the whole suite of tests is re-written multiple times, usually when it is discovered that the design needs to be changed, which even happens when a project has been thoroughly thought out, not to mention when it hasn't.

Finally, if a software developer has no alternative to starting a project outside of writing unit tests, then I would suggest that software development is not really the best field for that person. In the past decade, software developers were in high demand, and so it may have been the case that people who weren't ideal for the job were hired, simply due to a constrained supply of high quality software engineers. Just because an approach works and can get the job done doesn't mean that it is a valid or good approach. It just means that it's the best approach available, given the available options. If a software developer cannot come up with a design for a project and has to begin by writing unit tests, while that's better than nothing, it's only barely better than nothing, and falls way short of a proper workflow. Does TDD work? I'd agree that it does. But, don't get confused; it is not a better approach to coding than the many other ways out there, and often times it is worse.

I don't think there's necessarily anything wrong with trying out new ideas. That's how people discover better ways to do things. When TDD came out, it definitely was novel, and was worth experimenting with. But, it didn't take long for me to bump into the shortcomings I listed above, and 10 years in, I think everyone else should've also bumped into the same drawbacks by now, if not others that I don't have listed. So, the lesson to be learned here is: give new ideas and concepts time to age. Sometimes, they'll get better like wine; sometimes they'll rot. Sooner or later, time will tell.

Updated on December 27, 2023
Updated on December 27, 2023. © Copyright 2024 David Chang. All Rights Reserved. Log in | Visitors