On a strange turn of things, I am beginning to appreciate the practicality and utility of TDD. It has been over a decade since I first learned about it but only recently do I seem actually be learning it. Of all things, I seem to be making progress with it by unit testing in JS. As I said, strange.

A few things seem to have crystalized for me which has helped in this recent break though. They seem so banal in retrospect that it surprises me.

(1) TDD is not exactly test first. Rather, test drives. I used to agonize over making sure I never write code before tests but this seems to have been taken too literally. Code that is written to figure out what needs to be done, organize thoughts, or visualize an idea might as well be notes. Production code is what gets written after a test. This is a slight but helpful distinction.

(2) Tests won’t protect you from incompetence. I used to have a bunch of silly takes around this point. For example, thinking: You can still pass the test with a bad design, you can still write insecure code, you can still produce certain side effects, you can still do this or that. Of course you can. But why would anyone competent do that? This thinking is a race to the bottom. Tests won’t make a bad programmer good. If you don’t write good code, you probably won’t write good tests either. TDD is a better way to write good code.

(3) The preparation of the test requires a different “mode” of development/thinking. To do TDD, you need to switch between “set an expectation” mode and “fulfill the expectation” mode. This was helpful to understand why TDD can initially feel the way it does — jarring and unnatural. However, this does not seem unnatural at all when you think about how you automatically do the same thing (manually) when coding.

A common argument against TDD that still eludes me is exploratory work/coding. I suspect though this is similar to point 1. Exploratory work simply does not produce production code and is not a good area to apply TDD. Perhaps we shall see what more I learn in the next decade and whether this is the case or not.

Aside from guiding development, an interesting thing I have been seeing a few times are experiments with test driven design. However, I won’t try and integrate that with my mental model for now but definitely looks interesting. While I think in practice it would require a maybe impractical level of test granularity, the mere idea that design can be discovered rather than created seems, to me, quite full of groundbreaking implications.