Is Test-Driven Development good?
What is Test-Driven Development (TDD)?
If you have read some of the books on my reading list, you are most likely familiar with TDD. If that is not the case, Test-Driven Development by Example is a great place to start (it is a fun and brief read).
TDD is the practice of writing a test for a behavior you want, and once that test is proven to fail, you implement it with the most straightforward code possible to make the test pass. The final step in the process is to refactor (usally to remove duplication).
1 - Write a list of the test scenarios you want to cover
2 - Turn exactly one item on the list into an actual, concrete, runnable test
3 - Change the code to make the test (& all previous tests) pass (adding items to the list as you discover them)
4 - Optionally refactor to improve the implementation design
5 - Until the list is empty, go back to #2
– Canon TDD - Kent Beck
Does it work?
TDD is extensively mentioned in many popular programming books and with great reverence. It’s probably because they all have benefited from using it, one would hope. Here are some excerpts from some of these books.
We see a major benefit in TDD for people just starting out with testing.
– The Pragmatic Programmer - Andy Hunt & Dave Thomas
Done correctly, TDD can make your code quality soar, decrease the number of bugs, raise your confidence in the code, shorten the time it takes to find bugs, improve your code’s design, and keep your manager happier.
– The Art of Unit Testing - Roy Osherove
When used properly, TDD also helps you improve your design, documents your code for future programmers, enables refactoring, and guards against future mistakes. Better yet, it’s fun.
– The Art of Agile Development - James Shore
This test-code-refactor cycle should occur many times per hour, and can be a very productive and calming way to write code. I’m not going to discuss it further here, but I do use and warmly recommend it.
– Refactoring - Martin Fowler
One of the best ways to design and develop software is to think about the result you want to get right from the start. Many professional software developers do this using a formal process called test-driven development, or TDD.
– Exercises for Programmers Brian P. Hogan
Test-driven development and continuous refactoring, two of the many excellent XP practices, have dramatically improved the way I build software
– Refactoring to Patterns - Joshua Kerievsky
we think test-driven development is essential to enable the practice of continuous delivery.
– Continuous Delivery - Jez Humble & David Farley
Is TDD a silver bullet then?
That is a lot of overwhelming praise for TDD; it’s even considered essential to Continuous Delivery. Surely, TDD is not magic that fixes all problems. Here are some more excerpts showing the other half of the coin.
Test First, including Test-Driven Design, is probably your best choice in most circumstances, as it ensures that testing happens. But sometimes that’s not as convenient or useful, so Test During coding can be a good fallback, where you write some code, fiddle with it, write the tests for it, then move on to the next bit.
– The Pragmatic Programmer - Andy Hunt & Dave Thomas
A discussion of test-driven development is beyond the scope of this book. It is, however, worth noting that as with all such practices it is important to be both disciplined and pragmatic about test-driven development.
– Continuous Delivery - Dave Farly
For all its good points, TDD is not a religion or a magic formula. Following the three laws does not guarantee any of these benefits. You can still write bad code even if you write your tests first. Indeed, you can write bad tests.
– The Clean Coder - Robet C. Martin
TDD isn’t perfect, of course. TDD helps programmers code what the intended to code, but it dosn’t stop programmers from misunderstanding what they need to do. It helps improve documentation, refactoring, and design, but only if programmers work hard to do so. It also has a learning curve: it’s difficult to add to legacy code bases, and it takes extra effort to apply to code that involves the outside world, such as user interfaces, networking, and databases.
– The Art of Agile Development - James Shore
What does the studies say?
There are some studies made on TDD and its effectiveness, but there is no real conclusive answer yet if TDD is worth doing. Should we wait for this answer before it’s reasonable to invest in learning TDD? Probably not, because few things we do in software development are scientifically proven.
studies are mostly conducted with subjects who are not proficient in TDD; studies in brownfield projects with real-world tasks are in a minority; a large body of research has compared TDD against traditional development techniques; and finally, we noticed a lack of attention to the long-term effect of TDD.
Misconceptions
Sometimes people get it wrong and judge TDD not on what it is but what they think it is. In the next excerpt we can read that the author have misunderstod TDD, propobly because they did’nt read the littrateure.
Two vital points that makes TDD effective is that it’s incremental and iterative when writing the tests and the code (reread the excerpt from the What is Test-Driven Development section above if your memory is foggy)
Test-driven development is an approach to software development where programmers write unit tests before they write code. When creating a new class, the developer first writes unit tests for the class, based on its expected behavior. None of the tests pass, since there is no code for the class. Then the developer works through the tests one at a time, writing enough code for that test to pass. When all of the tests pass, the class is finished.
…
Although I am a strong advocate of unit testing, I am not a fan of test-driven development. The problem with test-driven development is that it focuses attention on getting specific features working, rather than finding the best design.
– A Philosophy of Software Design, 2nd Edition - John Ousterhout
Isn’t Test-Driven Development dead?
David Heinemeier Hansson wrote a blog post claiming that TDD can harm the quality of the production code. Listen to the hangout discussion with Martin Fowler and Kent Beck, and read Robert Martin (Uncle Bobs) thoughts to judge for yourself.
You’re doing it wrong
A common complaint from people who have tried TDD is that they liked it until they needed to change some code and found that many of their tests broke and that it was tedious to change the tests when you changed your code. Your tests are telling you something, and you need to listen. Tests should not brake if no behavior has changed.
It’s easy to fault TDD when you don’t get the desired results. The problem might be that you had the wrong expectations; more commonly, I see people lacking in skill and giving up when encountering issues instead of learning from them.
TDD will not work well in all situations, but that is not a reason to cast it aside as something that is not worth getting good at. Like anything, it will take time to get good. You can’t excel at something without study and practice.
Ian Cooper’s talk TDD, Where Did It All Go Wrong he states that it’s probably a good idea to reread the original TDD book from Kent Beck, Test-Driven Development by Example, but don’t stop there, seek out mentors, practice, read books on the topics of testing, design, and refactoring. I belive it will be one of the better investments you can make in software development.
TDD does require some knowledge about the language you’re using and a little more experience than the beginning developer has out of the gate.
– Exercises for Programmers - Brian P. Hogan