There are too many reasons to recount in full why Test Driven Development (TDD) is great: finding bugs early, getting double-sided checking of code (test vs. code, how do they match up?), it drives good API design, tests effectively document what your code is supposed to do, it saves time on regression testing etc, etc.
But the reason above all I love TDD is that it gives me the courage to change and add to code long after I or someone else has written it. I’ll know in an instant if I broke anything. Changing code I just wrote is usually not a problem, and most of the time my code is relatively defect free after years of honing my skills. But a lot of the time, I’ll write something, then let it lay for months before I see any need to go in and add or fix anything. This is the point when my recollection of potential knock-on effects of changes is starting to be poor, when I’ll struggle to have confidence my changes don’t break anything even if I wrote the original code.
This is the point when TDD really pays dividends: months after it was originally done. I know, in binary pass or fail immediately if I’ve broken anything. Non TDD projects will usually have a spurt of productivity early on, with diminishing returns later as defects and fixing bogs progress down. With TDD the productivity will be evenly distributed throughout the lifecycle of the software, it might even increase with time, as parts can be reused, and the reuse can be quickly tested based on adding to the existing test suite.
TDD is not instant gratification, which is probably why most developers and managers don’t get it. We live in an instant gratification world. But the long term dividends of TDD in terms of courage to change things months down the line while keeping productivity even or improving are massive compared to the alternatives.