Today one of my peers gave a presentation on test driven development, he mentioned several advantages of TDD and it seems to be an effective practice. However, I was wondering what some of the disadvantages are and in what cases might it not be wise to use TDD?
- You should teach developers to write tests
- Test writing is time consuming
- It's complicated to judge test completeness
- TDD may not work due to project workflow and features
- TDD doesn't give you confidence that the code works
- You should rewrite tests too after changing some API, for example.
The one situation where I've found TDD unworkable: If other people are changing the same code without using TDD, or without at least keeping the existing tests current as they change the code.
You could count that as a disadvantage: You can't effectively adopt it by yourself if you're working with others on the same codebase.
For one it may be that the software will be developed to comply with the predefined tests only...
Addendum: According to the comment by Dale below, I believe what I've written is correct. A set may not necessarily have more than one entity. And as per the comment, you write one test and then some piece of code/software to pass that test. This implies that a test is defined prior to development and then code is written to pass that test. So even if you write one test at a time or a group of tests and then write code to pass it, is it really the right way? OR should you be thinking and defining tests to see if the software meets the quality standards as defined by the people who matter.
We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.
In my experience the biggest hurdle for TDD is that you need a clear specification and, preferably, traceability between specification items and tests so that if the specification is revised you know which tests to change.
Sadly in many organisations that I have worked with the specification is released at Issue 1 between a week and a month after the code has entered final acceptance testing.
The other thing is that ideally the tests are a) written by someone else & b) black boxes - then you write code that passes the specific tests by writing good robust code rather than writing code to pass the test you just wrote.
Generally, there aren't really any problems with TDD. More precisely, the problems with "it" are more a result of not employing it correctly at the right stage of the feature / project.
When you are writing an API, you must first understand the problem, understand how you want to solve the problem, understand how you want to model the problem such that the consumer of said API is productive with your API. Once you have stubs and modelled your interactions, proven your approach using PoCs, and you get the warm and fuzzy feelings from your approach. Then you can write your tests and then your code, and then you may feel free to refactor.
The point is, aside from PoC work, you don't want to write any code until you have the basis for your API figured out: not test code and not API code. I think many developers skip this part and start doing the TDD thing (or go straight to implementation) and grow their solution organically. Anyone who subscribes to TDD can be just as guilty as the "ley" developer of building a terrible solution: you just want to make sure your keeping what really matters in the forefront of your mind: problem, solution, API surface.
The only other thing I'll add is that many people can be extremely productive with TDD, but your UX guys may not care for it. In other words, they may not be as disciplined as you so all you are doing is making them far less productive.