Many of the software engineers I talked to told me that they practice TDD out of guilt.
That's not right, we need a different way to think about TDD.
I've been practising TDD for almost a decade, here's how I currently think about it:
Current literature focuses on how TDD is the best design technique out there, therefore we have to adopt it.
But, I don't use a hammer merely because it's the best tool to drive nails, it's also because I can't drive nails without a tool.
Let's try that angle instead.
Effective techniques or tools circumvent our biological limits.
Usain Bolt can't outrun a domestic cat, but on a bicycle, he could.
When it comes to creative works, such as programming, our biological limits are in our heads.
It's difficult to recognise what our limits are when it's in our heads. We're not going to visibly bleed if we're not using any tools to drive those metaphorical nails.
Therefore I think it's important for us to describe what our limits are so that we can recognise and address them.
Here are three limits that I observed throughout my career:
1️⃣ Willpower
Not all of the work that we do to keep the business running is interesting or exciting. To motivate ourselves to do the work, we use our willpower.
Unfortunately, willpower is a resource that depletes quickly. We will run out of mental energy, which is quite limited per day.
That dopamine boost coming from chasing something shiny is also hard to resist.
We need to have an alternative resource to motivate ourselves.
2️⃣ Working memory
There is a lot of information that we have to juggle in our heads to ship a change. We need to think about the user needs, UX design, architecture, engineering principles, tech debts, writing tests, those old libraries, and the list goes on.
Unfortunately, we can only hold 7±2 things in our heads at the same time. We often think about the wrong thing at the wrong time e.g. we would refactor or optimise before our code is working.
We need to have the right information in our working memory at the right time.
3️⃣ Wit
We need to apply our intelligence to our work. There are many business and technical challenges that we need to solve, therefore we would think about the best solution to tackle all those challenges.
Unfortunately, our wit often introduces a whole set of new problems. We don't spend enough time thinking about simpler alternatives. We try to be clever at the wrong time.
We also tend to jump to conclude that we know enough about what needs to be solved and start coding without thinking ahead.
We need a system that helps us control when or when not to be clever.
Those three limits are what we need to circumvent, and we need a technique to help us work better.
The answer to that is an effective workflow.
Seriously, a workflow?
Yes. Niklas Luhmann famously wrote more than 70 books and 400 articles on various subjects. The amount of writing he had written is not only a matter of quantity but of quality as well.
The secret to his abnormally impressive productivity is his workflow.
What does an effective workflow look like in our software engineering world?
I'll describe them below whilst connecting them to TDD.
1️⃣ Effective workflow forms a positive feedback loop
The answer to our limited willpower is not stronger willpower, but to think about how we can live without willpower. The answer to this in creative works is a positive feedback loop.
We motivate ourselves by making a progress, and we know we're making a progress by getting feedback. The best kind of feedback that we should look for is the feedback that we get from the work itself, which will create a feedback loop.
When you practice TDD, every time you make your red tests turn green, you are making a progress. That's a positive feedback loop.
2️⃣ Effective workflow embeds a sequence (via a mnemonic device)
We would like to fill our working memory with the right things in the right sequence. A mnemonic device helps us remember this. We can recite the sequence of the alphabet by singing the ABC song as a mnemonic.
TDD's mnemonic device is Red > Green > Refactor. Each of these steps pulls different information into our heads in the right sequence, circumventing our working memory.
The separation of Green and Refactor is also the answer to circumvent our wit. The green step encourages us to think simple. What's the simplest way for us to make this red test green? That will reframe our heads differently.
3️⃣ Finally, effective workflow enables flow state
Flow state is correlated to happiness. Who doesn't want to be happy at work?
The prerequisites of a flow state are clear goals and immediate feedback.
Each of the steps in TDD defines clear and smaller goals for your task.
Each of the completion of the step, each of the green tests you're getting, and each of the commits you're making after the refactoring step is a form of immediate feedback.
In summary, an effective workflow is required to organise our heads better and circumvent our biological limits.
TDD may not be an answer for everyone, but it's one of the workflows that I found effective so far (I do have other workflows that complement TDD).
If you have a workflow that circumvents our limits, I'll be keen to know.
And don't feel guilty if you don't practice TDD!