The TDD Thinking Hats
When working with people who are learning test-driven development (TDD), I have a habit of talking about “the hat we’re wearing”.
This comes from reading the book Six Thinking Hats.
The premise of the method is that the human brain thinks in a number of distinct ways which can be deliberately challenged, and hence planned for use in a structured way allowing one to develop tactics for thinking about particular issues.
When a group wears a particular hat, they engage and discuss an idea in a deliberate way. For instance, if the group wears the yellow hat, they should think positively about an idea, even if that feels unnatural to them. This means everyone explores positives in something, even if individuals within the group have some biases against it.
I’ve seen developers who mix up the steps in TDD, where they are refactoring whilst the tests are failing, and they are trying to introduce new behaviour at the same time. These same developers frequently skip the explicit refactoring step too, so they make the whole process more difficult and still end up with code that requires a lot of improvement.
I find trying to have a more focused, deliberate mindset during the TDD steps helps me practice it more effectively, simply, and avoid some common TDD pitfalls.
This posts attempts to describe the hats you should wear during the TDD steps.
TDD feels right when you’re not wearing any single hat for a long time. If you’re switching through them frequently, that’s telling you that you’re iteratively making positive progress on the system.
When writing a new test: The green, ambitious hat
Write the test you want to see
In this situation, we should be consumer focused, and optimistic about the kind of code we’re going to write.
It can be helpful to ask yourself:
If this code already existed in the open-source world, how would I want to use it, and how should it behave?
Try to be ambitious, you get to design a great API by describing how it would be used by a consumer, in this case your test.
Take pride in the test you write, keep asking yourself whether the test describes the what and why effectively. Have empathy for your colleagues who’ll be reading and maintaining these tests.
At the same time, think about how you can cut scope sensibly, so you are confident that you’ll be able to make the test pass and have this positive change committed to source control in a reasonable amount of time. Have an eye on the end-state, but keep thinking about each small step toward that goal.
Aim to wear this hat frequently, but for short periods, so that you’re working iteratively with fast feedback loops on your decisions.
But, I don’t feel confident
This is normal! The first step, is often the hardest. There can be numerous reasons why writing a test is difficult:
The existing test suite is a hot mess
Adding a new test to an existing suite can be difficult for various reasons. Perhaps the existing tests are poorly written. Often they are a reflection of poor design, such as lots of complicated mock setup.
This might be time to reflect on the design of the code, and it may be prudent to pick up the blue hat to update the design of your system to facilitate the next change.
I don’t really know what I’m trying to make
Talk to your colleagues and stakeholders. Ask them what they think might be the first valuable step. If you don’t understand the problem you’re trying to solve, it’s going to be impossible to write a test for it.
You may wish to invest some time moving up a few abstraction levels to create an acceptance test to give you a more clearly defined north-star.
When the tests are failing: The red, uncomfortable to wear hat
When practicing TDD effectively, you’ll wear this hat frequently, but it should feel deliberate when you do, and you should never be wearing it for very long.
When the tests are failing, you should feel uncomfortable. Your software is not working correctly.
Endeavour to get the tests passing (green) as quickly as possible.
You’re not safe to make changes that are not directly related to passing the test, as you’ve lost your safety net. Any further changes not dedicated to making the tests pass can make the situation worse by adding confusion and complexity.
Make the test work quickly, committing whatever sins necessary in the process.
-- Kent Beck
It’s important to be thinking about good source control practice. Once you get the tests passing again, commit your changes. If you ended up wearing this hat during refactoring, it’s often better not to be precious about the code you wrote, just revert it.
Stop wearing multiple hats at once
In my experience, many developers wear too many other hats whilst wearing this one in particular, and can make life difficult for themselves because introducing more changes tends to make the failing test situation worse.
Too often, developers worry too much about writing "beautiful code" and get distracted from our short-term goal, which is to make the software work. We’ll have time to make the code great once we’ve made the test pass.
When you’re refactoring: The blue, confident hat
We are free to be creative! Maybe you were thinking about a design with the Red hat or the Green hat on - now is the time you can try it out.
We feel safe to make improvements because we get fast and reliable feedback that whatever changes we’re doing are valid. This allows us to aggressively refactor and take pride in our work.
- Make a positive change
- Verify the change is valid by running your unit tests.
- Commit the change to source control
- Go to 1
All our efforts are backed by tests against real, desired behaviour, so design decisions we make will be “real”, rather than for imaginary concerns.
When wearing this hat we get to improve the code, experiment and learn what works. Be brave and try different approaches to improve the code. If it doesn’t work out, it’s not a problem, as you’ll always be able to get back to working code with a
git checkout src/whatever.
Wearing this hat frequently through your day will steadily make you a better developer because you get more chances to experiment and learn.
If you have an idea for an improvement that you think will take many hours, pause for a moment. It might be worth going through a few more TDD cycles before making this commitment. By adding more tests, and therefore more behaviour; you are giving yourself more concrete information to make better design decisions.
Like the other hats, don’t let your head get hot wearing it for many hours in a row, as you might end up in a refactoring rabbit-hole. Little and often is the key.
Wearing the hats while pairing/mobbing
Six Thinking Hats says that everyone should be wearing the same hat at the same time, so that the group remains focused on the particular task, and you don’t end up moving in different directions and getting distracted.
For instance, the group could be wearing the red hat, but you can see a way the code could be improved. Don’t break the group’s flow, just take a note and bring it up when you’re all wearing the blue hat. Remember, if you’re practicing TDD well, you’ll be switching hats frequently through the day.
If you’re a more experienced member of the group, perhaps you can try using this thinking tool as a way of moderating how your team works through a problem more deliberately, and with better focus.
Do you wear these hats?
To those who feel confident and proficient with TDD, do these feelings and behaviours resonate with your experience? Do you disagree or do you have anything that’s missing here? Please reach out to me on Twitter.