Testability as a design metric didn't seem to be mentioned in all this.
When I started looking into Unit testing & TDD, I was surprised I didn't see any sort of style guide for it. Lots of stuff like that available for OO, C++ templates, etc. But I wasn't satisfied with what I saw in this area.
It's only now that I really appreciate a REPL for this purpose. Some sort of way for a developer to interact with live running code, without having to trace it in a debugger, is very, very useful.
But, REPLs aren't available for many languages. Instead, you end up designing code that's easy to test. I'll test every class with logic in it, but only the methods with real code in them (+ a little extra, b/c I don't trust my ego on this).
The code tends to feel dumber, but the development process becomes more linear, as I get it more right at the time of that initial test development than I would otherwise. E.g. I don't have to go back to it to fix bugs later, which is more painful as I've already forgotten my thinking on some of that stuff.
For me the highlight of this post is the idea (that I think I only absorbed about a year ago, after over 3 months of testing) that testing, much like project management, is a practical toolkit, not a theoretical framework.
What this means is that you don't need to come up with The Way of doing testing correctly - just apply the tools and techniques that seem to work best for the current context, even if they're in contradiction with something that you did before on another project or even in another part of this project.
I find that unit testing can really corrupt a program's structure. Especially dependency injection which takes a normal top-to-bottom flow and flattens it out to a degree that makes it hard to decipher what is actually happening. So instead of A calling B calling C, C will be injected into B which will be injected into A and then the whole thing will be unwound. On a large scale it can start to look like interface soup. Perhaps interface-oriented programing would be a more fitting name than object-oriented. It certainly doesn't look like the classical OO style.
Having said all that, I would be loathe to give up all my regression tests. The freedom I have to change major parts of the program knowing I have all the tests watching my back is invaluable. As is the benefit of being able to codify my hard won knowledge about edge cases and the like which I'm bound to forget and lose track of.
I just wish I didn't have to give up a more natural coding style to get the benefits of unit testing. Perhaps a language designed from the ground up to support unit testing is the answer?
Well by "corrupt" I mean to alter it from its original form or intention. Probably not the best choice of words I must admit.
"Decoupling" is a very useful tool. I think Joel's point of view was that unit testing often takes it to an extreme where the work to manage it outweighs the benefits. I personally don't agree with him. I think the benefits are too great to ignore. But I can certainly empathize with where he's coming from.
When I started looking into Unit testing & TDD, I was surprised I didn't see any sort of style guide for it. Lots of stuff like that available for OO, C++ templates, etc. But I wasn't satisfied with what I saw in this area.
It's only now that I really appreciate a REPL for this purpose. Some sort of way for a developer to interact with live running code, without having to trace it in a debugger, is very, very useful.
But, REPLs aren't available for many languages. Instead, you end up designing code that's easy to test. I'll test every class with logic in it, but only the methods with real code in them (+ a little extra, b/c I don't trust my ego on this).
The code tends to feel dumber, but the development process becomes more linear, as I get it more right at the time of that initial test development than I would otherwise. E.g. I don't have to go back to it to fix bugs later, which is more painful as I've already forgotten my thinking on some of that stuff.