Test-driven development is a way of writing code that involves writing an automated unit-level test case that fails, then writing just enough code to make the test pass, then refactoring both the test code and the production code, and repeat.
> https://en.wikipedia.org/wiki/Test-driven_development
One of Test-Driven Development (TDD) main goals is to make sure you write tests and don't skip them. While this goal is good, I don't think TDD is the best way to achieve it. Why?
Strategic Design vs. Test-Driven Tactics
Software projects, especially medium to large ones, need strong designs to handle inevitable changes. To do this, we begin by strategically designing the project.
Software design looks at the whole system first, then digs into how each part will work together. This requires thinking about the structure (big picture- Stratigic) before digging into the smallest parts (which the unit tests are concerned about). As design ideas mature, the structure becomes clearer and more detailed.
Software Design is a continous process, it usually starts with diagrams, RFCs, and (God forbid) UML. As you explore the problem deeper, more details emerge, you find another aspect that you need to take into consideration. This growth isn't always smooth, but it generally expands over time. During this evolving process, code is always being written, changed, and reused. The TDD approach would make us less adaptable, slowing us down and hurting productivity.
TDD can be showcased as a guide for small-scale design decisions, and in some reallife situations requires you've already or mostly solved the problem in your head (even if it’s in theory says it’s not). It’s “test-first” requirement is not suitable when the design is bigger and changing in scale.
With over seven years in software (which is not much, I know, but also not little), working on various projects for many companies, I can barely recall a single project that was fully figured out or even most of it from the start. Things constantly changed. Starting with tests first makes the primary goal of development simply passing tests. The focus shifts to getting "green checks" on the screen, losing sight of solving the overall product design.
I Still Like Unit Tests
That said, I love unit tests! I use them to make sure to protect my code ( or at least a considerable part of it) from the mysterious future, and immature changes.
And yes, they aren't much fun to write (at least for me). But I don't need to enjoy them to see their value. My favorite part is when a test I wrote fails after I mess something up during coding. It's a great safeguard, preventing minor mistakes from becoming major production outages. I'd much rather see red text on my screen than a massive problem for my silly bugs.
For me, unit tests typically emerge after the initial code for a module or feature has been drafted, or sometimes in very tight cycles alongside the code as its design solidifies, but never as the initial driving force.
I like my development to be drivin by strategy not green text.