Procrastination Driven Development
…and other real world alternatives to TDD
We've all heard of Test Driven Development, and maybe even tried it. It's not my favorite way to write code - it feels like navigating along a highway by bouncing back and forth between guide rails you're rapidly installing right before you hit them.
In this post, I'm going to explain some of my actual favorite ways to write software.
Procrastination Driven Development
Also known as procrasti-coding, this is when you write software to avoid doing a less desirable task. Performance reviews, expense reports, documentation, and that conference presentation coming up next week are all great choices. Be careful not to overuse this method - it can lose its power if it is abused.
The go-containerregistry library, used to interact with container registries by dozens of projects was written this way. In one of my proudest moments, I created a repository and skeleton with Matt Moore right before Google’s performance review cycle started. Looking for anything else to do instead, a volunteer group of engineers did the rest!
I don’t have the research to back this up, but I would bet more bugs get fixed and more documentation updates happen during performance review week than any other time at my current company. I also have a theory that spring cleaning happening at the same time taxes are due is not a coincidence.
This tactic can also work for things other than code! In fact, this very blog post was written in an effort to procrastinate from finishing a much harder one. The famous author Neil Gaiman wrote American Gods and many other novels this way as well. He described his method of forcing himself to write by sitting in an empty hotel room in this excellent Tim Ferris interview.
Documentation Driven Development
When you write the docs before writing any code. This strategy is similar to the ideas of paper prototyping, and can be a very effective method.
Instead of jumping into code or writing a spec or PRD as a starting point, you write the final end user documentation first. This forces you to think through the user experience at a level of detail that's hard to do otherwise. Features or workflows that are hard to explain to the end user are an obvious smell that you can detect early, before any code is written. Changing docs is much cheaper than changing code. And when you do eventually write the code, you're ready to ship because the documentation is already done.
As a side benefit, a project that launches with docs and no code looks much much more professional and production-ready than one that launches the opposite way - code and no documentation. The Tekton CD project is by far the project I'm most proud of, and Christie Wilson and I strictly followed Documentation Driven Development for the first several launches.
Deadline Driven Development
This one should be familiar to most developers, but there are a few variations that are worth explaining in more detail. The primary factor is rushing through implementation to meet a deadline. The deadline might be real, like an agreed upon date with a customer or a presentation at a conference. This is sometimes called Demo Driven Development.
The deadline could also be arbitrary - the end of a sprint, the start of the next quarter, etc. This strategy is also known as time boxing and can be used to control the scope of a project and coordinate large efforts. It can also easily be abused, resulting in the creation of technical debt.
Name Driven Development
When the name is so good you have to build it. The Skaffold project was built this way. We fell in love with the name so much we just had to get a team together to build the tool. It now has over 6k GitHub stars!
This can come in a few varieties, but the common trait is when your coding session is fueled by anger rather than caffeine. Or maybe both.
One version is when you're disgusted or embarrassed by your code. We've all been there.
This is usually a bad idea, but you gotta do what you gotta do. Sometimes it’s your only option! Just like Sherlock Holmes once said:
Once you eliminate the impossible, whatever remains, no matter how hacky, must be the design.
In the Tekton project we built an awesome system for retrieving logs from running tasks this way. The approach has been featured in numerous conference talks, and so far everyone agrees this is the best approach after an initial period spent making faces normally reserved for standing next to a PortaPotty.
Another case of this is when you're so mad at bugs in another piece of software, you write your own version out of anger. I'm sure some actual software has been written this way, but for me it always turns into the realization that software is harder to write than you thought. This phenomenon is also known as The Programmer’s Credo:
Resume Driven Development
When the primary motivation is not to solve a problem, but to pad your resume. Promo driven Development - doing something because you think it will help you earn a promotion and Fad Driven Development - building something to try out a shiny new piece of technology are similar
I'm not going to give an example here :)
YAML Driven Development
This is a new type of development that I really enjoy. The rise of Kubernetes-style declarative APIs has allowed for a new method of development. Similar to Documentation Driven Development, this technique starts with an outline of the design of an API in the form of YAML. Rather than iterating on schemas or APIs, developers prototype the YAML objects they would like to be able to work with.
Once these examples are settled and agreed upon, the formal schema is extracted and the code is written. This technique can also be used in systems other than Kubernetes. Golang interfaces work very well for this style, I'm sure other languages have similar features. It wouldn't be wrong to call this API Driven Development, but I prefer this name :)
We used this technique along with Documentation Driven Development for all of the original Tekton APIs.
Not to be confused with the technique involving clowns and monkeys sometimes used to write software for airplanes, this is when you write something on an airplane, or in another place where you don’t have an internet connection. This is related to procrastination driven development, you’re so bored by the in-flight entertainment that you finally build that thing you’ve meaning to get to forever.
The main difference is the lack of an internet connection though. This is helpful in that you can't check Twitter and get distracted while your code is compiling, but it also means you can't easily check API docs or look things up on StackOverflow.
My good friend James Strachan once told me that the first version of the Groovy programming language was written in an airport waiting for a delayed flight.
When you hack something together quickly and through a mysterious chain of events it ends up in production for years.
Do you use any of these techniques yourself? Have any other suggestions? Please share with me on Twitter!
Special thanks to Christie Wilson, Jason Hall and Kim Lewandowski for helping brainstorm these.