In the not-too-distant future, we are going to finally stop hearing about Test-Driven Development. And by this, of course, I mean that the “Test-Driven” part of Development will just be assumed, because everybody will be writing code that way. In the meantime, you and your team can either be ahead of the curve or not.
Here’s why I’m so sure.
TDD takes less time.
You heard me. Less. But how could this be? Writing unit tests every time we write code basically means we have to produce twice as much code, right?
Yes, tests are additional code that must be written, usually in a one-to-one ratio with the production code. But to argue that twice the lines of code takes twice the time to produce is short-sighted–it only makes sense if you see your development team as the typing pool.
We do not type for a living. We define patterns in logic and data, and wire them together to build tools that people can use. And the fewer lines of code we use to do this, the better we are at our job. You don’t measure productivity by lines of code, do you? Then why would you estimate development work using the same broken thinking?
The measurable output of software development is functionality. Features. And features get done (and stay done) faster when we have confidence that the components involved are chewing gum and kicking butt. The test-first approach gives us this confidence.
It also, incidentally, yields less production code per feature. If you’re into that sort of thing. More on that in a second.
TDD keeps developers focused.
Do you want to talk productivity? Let’s talk productivity.
Every person who has ever gotten things done ever has had one essential tool in common: a to-do list. When we write tasks down, we are extracting them from the soggy, unreliable twerkfest in our head, and transforming them into an unflinching list of verbs. Only then can we stop treading water in an ocean of distractions and make a beeline for our next action.
If you have done TDD enough to warrant having an opinion on it at all, you know that writing a unit test before you’ve written the production code that makes it pass is exactly like writing something down on a to-do list and then doing it. Defining the next action in this way keeps us on task in the face of the deeply complex series of steps it often takes to implement a software feature.
Remember when I said that using TDD leads to less production code? This is due to the focusing effect that writing a test, and then making that test pass, has. We’re just oscillating between the red and green–there’s no step for gold-plated YAGNI in that workflow. Defining a new test every few minutes gets us in the habit of questioning, frequently, whether what we’re coding is actually called for by the feature.
TDD more than pays for itself.
The time required for functionally comparable development tasks is not linear over the life of a project. A rigor mortis sets in as the codebase grows, because every decision made by every nerd on every line of code narrows the number of choices that the next nerd can make. But if our code is protected from regression and organized well (say, by being wrapped in a cozy, cozy blanket of unit tests woven during development), this harsh curve flattens out.
Initially, while we are still learning and forming the TDD habit, development time may increase on the order of ten to twenty percent. Do not panic. This is usually where the developer (or manager of the micro- variety) gets nervous and start skipping the test-first thing, thinking that this will speed things along. We settle back into our old habits, entropy sets in, and any benefit that could have been had from TDD is lost.
But if we hang on tight through this dip and let the habit take hold, our estimates swing back to their normal size, and we notice that the only thing inflating them in the first place was a learning curve.
By keeping the code focused, protected, and consistent, TDD can drastically cut development, testing, and debugging time over the lifespan of an application. It is fragile and unmaintainable code, undetected bugs, and unforeseen design issues that cause a project to miss deadlines and blow budgets; not an up-front investment in quality and morale.
“TDD” will just become “D”.
When you get your head around the discipline of TDD, and the return on investment to be had from rocking it, it becomes difficult to see a future in which nerds and non-nerds alike don’t get behind it. Until then, teams of sad coders everywhere will keep chasing the short-term gains of Debug-Later Programming, emitting reams of sad, unsustainable code, and generally doing things that sad people do.
I mean, probably.