I remember being a technical lead at IBM, believing that my job included making sure that work was completed correctly and as quickly as possible. (Of course, I hadn’t read The Goal yet.) Looking back now, I can easily predict the outcome: I made myself a bottleneck because I feared delegating important tasks to other people. I assumed that they’d do work poorly and that I’d need to redo it. I judged that I could do the work myself in less time than it would take to explain to someone else how to do it. I know now that letting myself be a bottleneck is a bad idea, but I had no good way to explain why very well until a strange moment some time in 2009, when a long-awaited neural connection finally happened. I almost felt the crackle in my brain at the point of impact.
In 2006, Tim Ottinger had written about “Sooner, Not Faster”, an idea I’ve been spreading enthusiastically for well over a decade now in my work as a consultant. For example, I teach evolutionary design to programmers (including test-driven development), not so that they’ll write code more quickly, but rather to help them deliver solid, cheaper-to-maintain features sooner. I don’t see test-first programming as a time-saving technique so much as a technique for avoiding unnecessary work:
- Writing a failing test first encourages the programmer to articulate clearly what they intend to build before building it. This extra awareness gives the programmer more opportunities to notice going in the wrong direction.
- Running tests frequently encourages the programmer to build only what they need, because once the tests pass, they stop.
- Passing tests encourages the programmer to stop when they’ve written enough code, because once they can’t think of any more tests that might fail, they stop.
- Keeping the tests passing helps the programmer build confidence in changing their code safely,. When they see a helpful opportunity to improve the design, they feel more confident doing it now, rather than putting it off. Putting off that work involves planning it, writing down what you intend to do so that you can read that later, tracking it, remembering to do it, and feeling stress about not yet having done it. All these things have their cost.
These aspects of test-driven development don’t involve thinking more quickly nor typing more quickly, but rather avoiding costly mistakes (backtracking, rework, frustration, stress) and side-stepping unnecessary work (adding accidental complication, gold-plating features, gold-plating the design). I help teams by focusing on how to delivery a satisfactory result sooner, no matter how quickly or slowly they go during the individual tasks.
If I’d Known Then…
Now I wish I’d thought that way as a technical lead. Imagine that I had a backlog of 10 tasks that would take me 4 weeks to complete. Now imagine that someone else could perform a task, taking on average about 5 times as long as I do to complete it. If I delegated a 3-day (for me) task to them, then they would complete it in about 3 weeks, but I would finish my 9 tasks in about 3.5 weeks. Even though they moved more slowly than I, together we would finish the backlog 2 or 3 days sooner. I could even afford to invest up to 2 days in teaching them, which could increase their capacity for next time, creating more options for delegating work and finishing sooner.
The alternative involves asking the others to do busywork while I finish my backlog. This sounds strange, but look around you: is everyone working on the most urgent tasks all the time? Probably not.
Had I thought this way, I could have benefited dramatically. More important work would have been completed, I’d have learned how to delegate effectively, and I would have felt (and probably now feel) less stress.