If you aren’t familiar with it, test-driven development (TDD) is a software development practice where you write tests before you write application code.
TDD is something most computer science students are taught, but are never actually required to use. And you can get away without doing it for most of your coursework. (I have some thoughts on that here.)
At any rate:
Good tests make good documentation – both for you and anyone who might come onto your project later. Test frameworks like Jasmine and Mocha read like plain English. Name your tests in a way that describes the tested function’s behavior in a particular circumstance.
You’ll code faster. Even if writing a correct function implementation is difficult, pre-written tests will give you a clear target to hit.
You’ll code correctly faster. Keep your test runner open to get continuous feedback on your work. This will get you to a correct implementation faster than coding an entire module at once and then testing it.
You won’t forget to write the tests. Code without tests should make you uneasy, period. A comprehensive, passing test suite is reassurance to you and other developers that your code (probably) won’t break.
It provides a solid starting point for later work. Similar to #1. Also, if you pick a project back up after a few months, you’ll forget how most of the code works. Tests can be a reminder, and a tested code base can be a fallback if you suddenly break things.
It pushes you to write cleaner code. Long, complicated functions are hard to test. Simple tests and clear descriptions will naturally lead to shorter, more readable application code.
You’ll write more meaningful tests. With code already written, it’s easy to write tests that just pass instead of tests that confirm useful functionality. Imagine if your math professor only tested you on things you already knew – that wouldn’t be very useful!
Do you have more reasons? Drop a comment below!
- This is part of a 6-part series on clean code. It’s some of the most valuable reading I’ve ever done as a developer.
Top comments (5)
Another critical benefit to doing TDD is that there are many agile engineering practices that a team could adopt. And many of those agile engineering practices are dependent on having unit tests.
Andrew Fuqua covered a lot of these in his blog post Engineering Practices Necessary for Scrum.
Arlo Belshee had a blog post where he asks the question of how to show that the team is actually creating unit tests, Metrics: are we doing TDD?. Arlo Belshee was a colleague of mine at a previous employer - he's a great guy.
nice post. Thank you for your thoughts on that.
In my experience it is pretty different. During my studies, nobody taught us TDD. Of course we had some courses that showed how unittests are used. But that's pretty much it. TDD is so much more than unittests.
The link on "here" is broken. I would be very interested on your thoughts on that. What is the correct link?
I also have some feedback on your 7 reasons.
I'm not sure about that. Especially when you start using TDD, it will slow you down. BUT: I agree with the description of the point. You have a clear target. And that's important.
Another good point: Always leave work with a failing test. This will bring you right back into focus on the next morning.
Fixed the link, thanks for the heads-up!
I can understand TDD slowing down folks that haven't used it before, but I actually didn't experience that. Writing and passing one test at a time forced me to think about my code in smaller, more obvious pieces (read: shorter functions) and move faster from day 1.
Genius; I hadn't considered that.
Actually, where I studied, Unit-testing (let alone TDD) wasn't mentioned until a very late stage during my studies.
This is very unfortunate, and one of the reasons some devs are having a hard time to start writing tests.
These points you've made should be explained during the first CS intro course, this way it'll be easier for us to convince (if necessary) new devs to write unit tests and maybe even employ TDD.
TDD puts positive pressure on developers to do several of the SOLID principles as a matter of due course.
The primary key benefit to unit tests for TDD is that they guide the developer to make their code testable. Since the code is testable, and it is unit tested, it can be relied upon to have basic correctness. Which means the code is reliable and robust. And also malleable - it is capable of changing and will squawk if the change breaks something.
A synonym for testable code is decoupled code.
The secondary benefit is the byproduct of TDD: having a body of unit tests that enables refactoring with confidence.
The tertiary benefit is the legacy artifact of having that same body of unit tests that can be run in an automated fashion to catch any regressions of basic correctness.
The secondary and tertiary benefits are insufficient to justify creating unit tests. But the primary benefit is compelling.
Creating unit tests after the fact bypasses the primary key benefit to unit tests.
Also, some languages and IDEs are much more suited to writing unit tests than others. For example, I've used Visual Studio, using C# and NCrunch and NUnit testing framework.
Not only did NCrunch make unit testing a breeze, it also made it... dare I say... fun! Whatever magic pixie dust they put in NCrunch is well worth the price.
I wish I had something like NCrunch for C++. :-(