Here is an article about how a Java programmer can’t wrap his mind around the fact that Rich Hickey doesn’t do TDD even though all of said programmer’s friends agree that TDD is the best thing ever.
This was very interesting!
I think Dean makes some very good points, I don’t think he is too one-sided on this.
As a professional developer for 25 years who spent almost 20 of those years developing medical devices and information systems, I got used to testing every line of code I wrote. First I used a lot of sticky notes. Then I started thoroughly testing a module before modifying it. Then I got really good at remembering what was new code, what was tested, what was untested, and what code I considered stable (not likely to change again soon). I also got better at documenting my code, with comments, and external documentation. These were required because of FDA regulations, and because people’s lives were at stake. This dates back to the times before the internet, before we even heard of design patterns and refactoring and unit testing. We did all those things, just without the fancy names invented to sell books. I created good habits. I still use them. I still rely on them. I would prefer to do everything with TDD, but I feel as if I am one of the rare, few, old-timers that has enough good habits to do without it sometimes. People still misunderstand the benefits of TDD. The replies to this article mention many benefits of TDD, but they are really just benefits of unit testing, or testing in general, not specific to TDD. What IS specific to TDD, that everybody seems to miss, is that TDD makes you think about the requirements before you write the code to satisfy those requirements. It is an encapsulation of the coder’s understanding of the requirements, right or wrong. Another person can read the tests that were written BEFORE the code, and know they represent the FINAL version of the requirements before the code was written, i.e. they are in-sync with the code and the requirements. The coder who writes tests after the code does not gain this benefit. Many tests are written to pass with the code that exists as it is, they do not test the requirements, they trust that the code is true to the requirements, even if they are not. That’s what the key is, testing the REQUIREMENTS, before testing the CODE. If you can’t understand the requirements completely, you have to experiment with the tests, not with the code. You spend your time up-front, not on writing prototype code that was meant to be thrown away, but somehow makes it into production (tell me it doesn’t happen, I dare you), but on writing tests that never get released to production! Experiment with something that can’t be pushed into production in bad shape, the tests! When the tests make sense and are consistent with the other existing tests, you probably understand the requirements better before you’ve written any code based on them.
Coders understand tests when they look like code, not like VBScript. They glean the understanding that the coder had from the tests, and they represent the requirements, which often don’t exist or get lost. Unit tests by themselves do not give you this advantage, tests written after-the-fact are not based on the coder’s understanding of the requirements! They are not testing the requirements, they are just testing the code! I don’t know why this fact is lost on so many. I’ve done unit testing. I’ve done TDD. TDD is far-superior when you do not have solid requirements, documented, tested (who ever does this? everyone should!). TDD is superior when you are writing code that other developers must maintain. Without any connection to requirements, code just does what it does, there’s nothing to check it against, even the unit tests are often just made to fit the mold of the code, whatever it happens to be doing now, right or wrong. The refactoring methodology has encouraged this mis-use. Example: The code does something wrong, but nobody knows this, because the unit tests were written after-the-fact, by a different developer than the one who wrote the code. There are no requirements documents to check the code against. The unit tests are written prior to refactoring some legacy code, before rewriting it, per the methodology. Every step just propagates incorrect behavior, it’s the sound of one hand clapping! With no left hand to know what the right hand is doing, it’s hit-or-miss! TDD is code testing code, part of the code-base, a translation of the requirements, as understood by the coder, into CODE that other CODERS can understand! As long as those other coders know this was written with TDD, they can trust the tests as a consistent translation of the requirements into the production code, in a language that coders understand! This is far-better than forcing down-stream coders to reverse-engineer the code, and the requirements they were based on! I know! I’ve done plenty of that too! If you are a lone coder, working on code that nobody else will ever see or touch or have to maintain, and if you have a ton of good habits and a clear mind and good memory (anybody left?) then you can do without TDD, but I would still recommend it! Why? Because your own faculties will not remain as clear and sharp as they are now — forever! How often do we remember what our understanding of the unwritten requirements was when we wrote the code we’re looking at, say, a year later, or 3 years, or even 2 months later! People are squabbling over doing TDD or not, without even knowing the most valuable benefits! They’ve lumped TDD in with unit testing, and they should not be lumped together. TDD is not a testing methodology, it is a DEVELOPMENT methodology. It is not about having a suite of regression tests, that’s just unit testing! It’s about having better code, sooner in the process, based on a clearer understanding of the requirements, as a consistent, up-to-date set that is in-sync with the code. You can understand the code better by looking at tests written with TDD than non-TDD (if you know that TDD was used).
> TDD is not a testing methodology,
> it is a DEVELOPMENT methodology.
Bleh, TDD is for people not knowing what their code does. They are not thinking in the language they are writing.
Write once, write correct, screw the tests!
(disclaimer: regression tests are good though, but not this silly test first approach)
Notify me of followup comments via e-mail