Test driven development is a great practice. But, sometimes we definitely should NOT use it.
right. who's this guy and where's John??
Really, sometimes the practice of TDD isn't in the best interest of the business. TDD has pro's and con's.
Pro's
- better quality code
- actually does what the developer wanted it to do
- can safely change/refactor without worrying if we broke it
Con's
- test code costs time and money to write
- test code is overhead, it has to be maintained in addition to the main line code
- some test code can be complex and harder to understand than the code it tests
The reason we test software is to mitigate risk. The risks we mitigate can be many, but we ought to have business value in mitigating a risk before we write a test. Some projects are so small and temporary that it doesn't justify writing tests. The business isn't interested in mitigating too much risk from the small project or temporary utility that isn't already covered by the standard things programmers do to run their programs before they call them finished.
Unit Testing is a great way to document functionality and illustrate that it works as intended. But the time and effort spent on writing the tests must be of value to the business - in the form of risk mitigation. For shipping products and tools that decisions will be based on, yes it makes sense to test it all thoroughly. The risk of customer problems and complaints, or bad decisions based on erroneous data are too high to leave un-mitigated. So we need to test them well to mitigate the risk and give that value to the business. Other times we can say a risk is just mitigated by the fact that we are "willing to accept" the risk. Acceptable Risk is a term I have heard used in threat modeling - indicating that the risk is so small or the problem so unlikely that we recognize it, but live with the risk that it may someday occur.
Testing is overhead, so make sure that the testing done is appropriate. Make sure that there is recognized and enumerable risk that can be mitigated by each test. Make sure that all the tests (unit, integration, functional, etc.) are warranted for the software being tested. I don't recommend under-testing either.
In Agile, one of our fundamental tenets is that we always strive to deliver value to the customer. For me, I strive to deliver value with each and every line of code, both main-line and in tests. Test the right things, and only at the right time.