Category Archives: TDD

When I do TDD and when I don’t

Some developers advocate doing test-driven development 100% of the time. Other developers think TDD is for the birds and don’t do it at all. Still other developers go in the middle and practice TDD more than 0% of the time but less than 100% of the time.

I personally am in the camp of practicing TDD some of the time but not all. Here’s my reasoning.

When TDD makes sense to me

It’s not the case that I use TDD, or even write tests at all, for every single project I work on. But I do pretty much always program in feedback loops.

Feedback loops

The “feedback loop method” is where work as follows. First, I think of a tiny goal that I want to accomplish (e.g. make “hello world” appear on the screen). Then I decide on a manual test I can perform in order to see if that goal is accomplished (e.g. refresh the page and observe). Then I perform the test, write some code to try to make the test pass, perform the test again, and repeat the process with a new goal.

TDD == automated feedback loops

The way I view TDD is that it’s just the automated version of the manual work I was going to do anyway. Instead of making a to-do note that says “make ‘hello world’ appear on the screen” and then manually refreshing the page to see if it’s there, I write a test that expects “hello world” to appear on the screen. All the other steps are the exact same.

I’ve found that TDD works great for me when I’m working on what you might call “crisply-defined” work. In other words, the requirements I’m working to fulfill are known and specified. I find that I’ve found that there are other scenarios where TDD doesn’t work so great for me.

When TDD doesn’t make sense to me

Coding as production vs. coding as thinking

It’s easy to think that the reason to write code is to create a work product. But that’s certainly not the only reason to write code. Code isn’t just a medium for producing a product. It’s also a medium for thinking.

This is the idea behind a “spike” in Agile programming. When you’re doing a spike, you have no necessary intention to actually keep any of the code you’re writing. You’re just exploring. You’re seeing what it looks like when you do this or how it feels when you do that.

You can think of coding kind of like playing a piano. Sometimes you have some pieces of music already in your head and you’re trying to record an album. Other times you’re just messing around to see you can come up with any music worth recording. These are two very different modes of engaging with your instrument. Both are very necessary in order to ultimately record some music.

TDD doesn’t mix great with spikes

I often find that a spike phase is necessary when I’m coding, for example, a feature with known big-picture requirements but unknown UI specifics. In that case my test would be so full of guesses and placeholders that it would be kind of a joke of a test, and it wouldn’t help me much. In these cases I give myself permission to forego the testing during the spike period. I come back after I have some working code and backfill the tests.


  • I don’t practice TDD 100% of the time. (I believe I do practice TDD the vast majority of the time though.)
  • I view TDD as the automated version of the coding workflow that I already use anyway.
  • Producing a work product is not the only reason to write code. Code can also be a medium for thinking.
  • When I’m in the mode of using coding as a way to think, I find that the benefits of TDD don’t really apply.