Several years ago my wife decided to make custom multi-colored Christmas light strands by changing the individual light bulbs on solid-colored strands. The task seemed simple, if tedious, enough:
Step 1. Get 100 bulb strands of red, white, green lights.
Step 2. In each strand, skip one bulb, remove two and place into bins, repeat until end of strand.
Step 3. In each strand, take bulbs from the other two bins, replace lights in order, repeat until end of strand.
Step 4. Plug in each light strand.
We followed this process, and after an hour we were ready for step 4. Veteran Christmas decorators know what happened next.
Two bad strands.
Why? Christmas light bulbs are wired in series, meaning that one bad bulb will prevent the strand from lighting. For one more hour, we worked up and down the faulty light strands, looking for the bad bulb. We checked each bulb for a tight fit. Then we pulled each bulb out, furiously examining the connections, occasionally tweaking them. Every time we’d test the strand, we did not see any lights. Finally, we were able to fix all the strands. In total, we spent two stressful hours to create three multi-colored strands.
That night I laid in bed thinking about our experience. When we started, I felt great! We had an efficient plan. We would do the jobs in batches: finish one task (pulling out lights) before moving onto the next (putting in new lights). With no task-switching, it felt like we’d get done in no time. Unwittingly, we had followed the waterfall process of doing Christmas lights.
Our downfall, and the waterfall’s downfall, was not knowing where we introduced the errors. In that second hour, testing the lights like crazy but never certain that we were making things better instead of worse. In both hours, we were so busy that our perceived productivity was high, but our actual productivity does not. We did not introduce any testing until the end, like a software team that does not test until development is done.
I realized an agile, test-driven development process would be the way to go. We would introduce regular testing into our process. Instead of time-boxed iterations we used lightbulb-boxed iterations. On the next set of strands, we stopped and tested each of the strands every three bulbs. While we had a lot of task-switching, we also had a high degree of certainty. Each test, either the whole strip worked, or one of the last two changed bulbs was faulty. Progress was slow but steady. We finished and had three working strips in 90 minutes.
In the waterfall process of Christmas lights, we sped through the bulb changing (development) but got hung up in test. With the agile approach, our bulb changing (development) time increased 50% but the final test was a breeze. In each case, we made the same total number of mistakes, but in the agile approach we caught and corrected them faster.
Test-driven development is a powerful concept. In my software development career, it has made me a better software developer. My wife’s Christmas lights showed me how powerful agile techniques are outside the compiler.