Rethink About Test Driven Development and Unit Testing
If you are familiar with agile processes, it’s most likely you also know of, or even practice, test driven development (TDD). Several years ago I read the book Test-Driven Development by Kent Beck, and found the idea pretty interesting. After that, I rarely found myself using or even thinking about this methodology. I am not saying that test driven development does not make sense, but that it is not the approach working for me, and maybe some others as well.
According to TDD, you should write unit test code before writing your real production code. At high level, a unit test in some way describes a requirement for the real code to meet. This does not directly translate to requirement from users’ perspectives though.
When I tried to practice TDD, I found myself frequently jumping between tests and real code. To write test code first, I need to know what the real code looks like. That means I at least write the interfaces of the real system first.
If I have done the interfaces, it means the system is in good shape in terms of design. Then, I started to debate whether I should go forward with real code, or unit test code.
In the end, I always chose to go with writing real code. For one thing, I can show a quick prototype once I get the implementation partially done. While the unit test is good, it’s not part of the final deliverable. If you avoid it, you lose nothing in the end result. Of course, unit tests help on quality, but it’s not my primary concern in the early phase of a software project.
In reality, I always keep tweaking my initial interfaces, therefore I have to change affected unit tests as well (you see, the tests are actually driven by development). This essentially means more works. The result is that it can significantly drag down the development pace of your project. The refactoring tools help a lot to keep interfaces in sync, but if you change the semantics of interfaces, the refactoring tools can’t help too much.
You may ask, “why should you keep changing your code?” Well, no one can define a system in one shot. When more code is written, we either find holes in our initial design, or we find better ways to do something or structure the system.
In general, I think unit tests are extra works to worry about during software development. They are good to have, but not must to have. More unit tests most likely lead to, but are not equal to, better quality or more code coverage. They are better applied when the system start to stabilize after initial intensive development.
Personally, I don’t see TDD as a universally good way to develop software even though I see the value of unit testing. To be realistic, I think it should be changed to something like Test Enhanced Development. I believe that would better align with reality for most developers.