Your team is considering whether or not to adopt TDD. What are the benefits? How does TDD compare to TLD?
TDD provides shorter feedback loops. This means you get feedback faster, and rework takes less time.
TLD provides longer feedback loops. This means you get feedback later, so rework takes more time.
TDD: I start off with writing the requirement in an executable form (the test). I might discover that the requirement is unclear because I can't write the test! That's ok, I'll stop there, need to get the requirement clarified. Then I proceed to write the test, and as I'm writing the test, I'm modeling the contract for the code, to make sure it's consumer-friendly. Then, I then run it to see it fail, so that I can be sure that the test is falsifiable. (If the test doesn't fail, it could be due to incorrectly writing the test, or perhaps the functionality already exists, or I didn't reproduce the bug which I'm trying to fix). I proceed to write the minimal code to make the test pass. I run the test and verify that it's green. I can then safely refactor.
TLD: The "best case" of TLD (closest to TDD for sake of fair comparison) is, based on the requirement, to first write the code, then write ONE test. But, during writing the test, I might discover that I can't write the test because my code wasn't designed in a testable way! So then I have to rework BOTH the code and test. Great, I've now written the test, but I might discover that the way I'm calling the interface isn't really consumer-friendly (after all, the test is the first consumer of the code). To modify the contract, I have to rework BOTH the code and the test. Finally, I run the test to check it passes. Green, great! But how do I know that it's actually my code which caused the test to pass, or was it a false positive (case of the test always passing)? I don't know. To get that assurance, I'd need to comment out the code, run the test to see it fail, then uncomment the code, and run the test to see it pass. Then I can refactor the code.
What's worse? TDD does badly? Or TLD done badly? Which one causes MORE damage?
In worst-case TDD, we are guaranteed to have automated tests, that code is fully covered by the tests, that code is testable BUT other aspects of the design might not be done well if the Refactor step was skipped. But the good news is, we can improve the design because we have the safety net provided by tests.
In worst-case TLD, we will neither have automated tests nor will the code be testable. No tests, no refactoring possible. We stuck.
In summary, TDD is better than TLD even in the worst-case.
Worse-case TDD is when developers don't follow the Red-Green-Refactor cycle, but instead they just omit Refactor and do ONLY Red-Green. The result is - yes, we have tests, and yes the code is testable. BUT unfortunately, aside from testability, all other aspects of good design are missing, the design is really bad!
This occurs whereby someone mindlessly for each requirement writes the test, writes the code to make the test pass, BUT doesn't ever stand-back and look at the code and thinking about how to refactor it. Instead they just keep on adding to the existing design, without improving it. So then the design stagnates, and then starts rotting... For example, for each test case, someone decided to keep extending an endless if-statement instead of thinking about design patterns, and the code becomes unmaintainable, duplicated code, etc...
Worst-case TLD is when developers "just code", so they churn out code, don't pay attention to testability, manually debug code because they don't have time for tests. They see tests as inferior, as secondary, as beneath them. Their job is just coding, right? I mean, if they wrote the code, and ran it in the debugger and it works, then are tests really needed?
These developers theoretically know they "should" have tests (because some famous people in software craftsmanship said that you should write tests), but for them it's a formality, they will do the tests AFTER the code, because the code is what's most important. The tests are there just to satisfy some minimal code coverage that the Engineering Director set for the company.
By the time they get to actually writing the tests, they can feel the pain. Tests become so painful, so cumbersome, so time-consuming, such a waste of time! And the tests would actually force them to change the design.. So then, they complain to the management that tests take up so much time, and why should tests be written for something that works, after all they can work on the next functionality. And then the tests are written... never.