One problem I often hear about is that TDD is hard; and so teams come away with the idea that if they ignore TDD, and just write Unit Tests, they’ll get the value of TDD without the hard parts.
Let’s put aside for a moment that the tests are not the valuable part of TDD, and just go with the sentiment.
The desire to write unit tests lasts about as long as the team’s willpower to deal with the onslaught of issues they come across, but generally not longer than that.
At which point team members stop writing unit tests; or if they do, it’s because someone forces it as a part of check-in. That in itself speaks volumes.
Somewhere along the line our industry caught the belief that unit tests are valuable; and that they’re what teams should strive for. We’re all paying the price for that, though most of all the people that have to write tests because their definition of done says to.
Unit tests are a brittle, implementation (and thus point in time) specific method of determining the correctness of a particular approach to solving the problem:
They say nothing about whether the problem was actually solved, however.
Integration tests, for all their problems, at least can say with certainty that the problem you set out to solve was solved, whereas unit tests carry no such guarantee; yet with many of the same costs of an integration test.
We should push back harder against the idea of unit tests. It forces tests to follow code; and given production code that obstensibly works, no one is going to invest the time to change it to make it easier to test after the fact.
The missing ingredient to unit tests is that they don’t force you to change how you build software, because, let’s be honest, changing how you build software to make it testable is neither simple nor easy.
Building the political capital needed to bet the future of your company or your reputation on TDD is definitely not simple or easy.
Those are the roadblocks for any team that wants to build sustainable software: Learn; build political capital; change our style.
With those road blocks, why would you want to make it harder on yourself by writing unit tests because “that’s what you’re supposed to do”?
The answer is, You wouldn’t.
If code that’s easy to change and easy to check for correctness are things you want, then TDD can help you get there; but if you think you need to write tests because someone told you you should write tests without changing how you write code to be more testable; then take this as permission from me to not write tests. You’ll be happier, your team will be happier, and you’ll save yourself a lot of trouble.
Excellent points! I ditched unit testing in favor of integration testing years ago, and never looked back.