Why everybody talks about TDD, but actually noone does it?

Andrius Poznanskis
4 min readAug 25, 2017

--

As everybody is aware of, TDD is one of those things that many, including me, like to talk about, but only very few are actually doing it. And 99% of developers who claim they are doing TDD, actually just wanted to say they write tests.

So why is everybody still talking about it? IMHO, because it is really useful technique, which yields great benefits when applied to right places. The most obvious benefit — quality, nobody argues with that. Everybody wants to write quality code. Only there is a catch — to do TDD properly, you need to have immense amount of self discipline, and it take years of hard work to master. It’s just not that easy, you need to invest quite a lot in learning.

There is more to that though. TDD, while being quite universal tool, is not a silver bullet. It works well when you have stable requirements. Not so well for exploratory coding.

Now the truth is, most of our code is something that has already been done millions of times. Only that we realize that long after the implementation is complete. When we look at the code months later, start seeing patterns, and start wondering how could anyone have been so shortsighted then. This 100 line nonsense can be rewritten in 10 line perfectly clean code, while eliminating some obvious bugs in the process. So, had you seen that in the first place, you’d just have saved tons of time. What would it take to arrive at this clean solution from the first time? Well, in my experience, it takes a lot of thinking, discussions about the problem, and it requires experience to map it to something you’ve done before. If you have that experience, then you can do this entirely in your mind. But if not, then you cannot do that, period. You have to start experimenting and see what works, there is no other way. And so this is what I believe is happening with software development. People are reinventing the wheel all the time, because they don’t have experience. And experience is about trying it with your own hands. This is just how human brain works. You can gain experience by reading books, but to truly understand what you’ve read, you need to try it. It’s perhaps not as strong as with physical things, but still, it makes big difference. I’m not talking just about implementation patterns, I mean experience with frameworks, libraries, APIs, etc. This means exploratory coding. I think this is what most developers are doing most of the time. Because there is no other way — when you don’t have experience, you need to gain it.

TDD, and automated testing in general, has little benefit to exploratory coding. There is REPL for that. If you need to get experience with 3p API, it’s just better to poke it and see what it does. And delete all your experiments once you’re done. Not treat them as part of your system. It is probably a mess as it is already. Now testing 3p API is not necessarily as stupid as it looks, it can even be beneficial as some showcase usage scenario in your particular domain. But yeah, nobody would test String class, it has already been tested in all possible ways. I’m a C# developer myself, so ofc I’m using test classes to invoke my experimental code — just because the C# REPL in VS is utter shit. So this is the case where TDD doesn’t work, even TDD evangelists admit that. And this is majority of your work as a coder, things that will not see their day to live.

Usually, it’s not just exploratory coding, and it’s not clean perfect solution at first time, its something in between. You start with the things you know, then you figure out the things you don’t know. Or the other way round. The solution is a combination of patterns well understood, and adhoc code to “make this thing work”. And here TDD works very well for the things you know. You assert on them, and then make sure that implementation adheres. It can be top-down, or bottom-up. You can start with both high level decomposition of a problem, as well as with low level utility functions you know will be helpful. If you start top-down, then you haven’t checked your assumptions about the environment you’re gonna rely upon. Maybe that API you were expecting to use actually does entirely different thing than you thought. If you start bottom up, then you are potentially solving problems which will not be included in final solution. I think TDD works very well for top-down solutions, where you know high level structure and it’s gonna be stable.

TDD works well when you know what you’re doing. You assert “i know this thing to be true”, and then you make it so. And for most of problems, there are things that you can be certain about. On the other hand, there are things that you don’t know and need to figure out. And asserting on something you don’t know is just stupid. You first must get to know it. In programming as well as in RL. Doesn’t work any other way.

--

--

Andrius Poznanskis
Andrius Poznanskis

Written by Andrius Poznanskis

Interested in Computer Science and Software Engineering. And Cybernetics for that matter.

No responses yet