TDD or Test Driven Development is this religious virtue in software development. Write tests first before you write code. Sounds wonderful in theory but how often is it truly worth it? Here is my take on it.
TDD works great when you have a concrete idea. When you have decided on how something will work. When you have the design and UX in front of you. But when it comes to feature development, I think TDD is a bad bet. Tests should not be driving your product or your feature, but instead should be driven by user experience (UX). When designing a feature, you want to feel the experience yourself (and not through tests).
When TDD’ing on a feature, it is expected that you imagine the feature through tests before it becomes tangible. I’m not a big fan of that. I’d rather work on the real thing - the HTML, JS, backend before I write a test. And I’m not talking about writing full-blown meticulously designed interfaces before you write tests - just affordances.
That gives me a place to play with my idea (the real feature) before I start making hypothetical edge cases. Which brings me to my other issue with TDD - it makes you worry about something preemptively. Edge cases, performance issues, etc.
I was a TDD aficionado when I first heard about it. Every line of code I write should be driven by a test. Why open a browser when you can get results from your terminal!
Then I soon realized that writing tests very early in the feature restricts your ability to explore freely. Failing tests distract you from your primary agenda - which is the feature. You feel that you need to make them pass before you can continue working on the feature. There is also a lot of context switching between thinking about your feature and making tests pass. Perhaps you might hit a snag while making your tests pass making you go in all sorts of tangents.
With that said, TDD might be good choice in some cases.
- Refactoring existing code
- Implementing a functionality in isolation (Unit tests)
- Modifying behavior of existing features
I believe there can never be a stringent rule that tests should drive the code. It is more valuable to build something tangible. Even in the worst case scenario, you can scrape off the entire thing without having spent time writing tests.