Beyond TDD: breaking the rules
Tags: career, productivity, testing, tdd
Published: 2020-01-23 16:05:12

---
title: "Beyond TDD: breaking the rules"
published: true
tags: career, productivity, testing, tdd
description: Rules are made to be broken, right? TDD is a strict set of rules that define a process for building software. But experienced practitioners have moved beyond the rules and work towards something else entirely.
cover_image: https://source.unsplash.com/U5y077qrMdI/1000x620
---

*Cover image by [Mark Duffel](https://unsplash.com/@2mduffel?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/rules?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText).*

Rules are made to be broken, right? TDD is a strict set of rules that define a process for building software. But experienced practitioners have moved beyond the rules and work towards something else entirely.

[Ron Jeffries wrote a tweet thread](https://twitter.com/RonJeffries/status/1218539681660522497) in which he discussed the notion of what he calls **pure TDD** (**PTDD**), and is sometimes called **strict TDD**. He talked about how he doesn’t like to subscribe to this purest approach.

But **rule-breaking is an acceptable part of any skillful process.**

The [Dreyfus model of skill acquisition](https://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition) talks about skilled experts being _intuitively_ aware of rules and can make decisions without conscious thought. That means they know not only how to apply rules but also when to ignore rules.

Then there’s the [four stages of competence](https://en.wikipedia.org/wiki/Four_stages_of_competence) model which goes from unconscious incompetence&mdash;you don’t know what you don’t know&mdash;through conscious incompetence and conscious competence and finally to _unconscious competence_ which, again, is saying that experts are intuitively aware of what they’re doing without having to think about it.

## What does it mean to be intuitive?

In some sense, the word **intuitive** means you _no longer need rules_. Instead you understand the core values behind the rules, and work towards those values, not the rules.

Because you know the values behind the rules, you can understand the trade-offs involved. You can begin to see when the rules might not apply. You can begin to answer the question “when should I use TDD, and when should I not?”

Contrast this with TDD aficionados. Many of them will want to use TDD all the time, because TDD is **just so amazingly great when you get the hang of it**. (I’m not being sarcastic here; it really is great.) We have a phrase for this attitude: “[If all you have is a hammer, everything looks like a nail](https://en.wikipedia.org/wiki/Law_of_the_instrument).”

## When is it okay to NOT use TDD? When can I cheat?

Assuming then that you agree with me that it’s okay to move beyond the rules, then on what occasions should we do so?

Here are some I can think of.

 * **When you work with a team who aren’t versed in / don’t follow TDD**. Now your choice is to accept that fact and try to win them over, which probably won’t happen very quickly.
 * **When the risk is low**. This is an interesting one, because the more experienced you get, all those functions and objects start to look the same. That means development becomes less risky because it’s familiar. Then again, your risk of mistake goes up if you’re tired, or working alone. There are many considerations. Knowing how to weigh them up can take considerable experience.
 * **When the cost/benefit ratio is not in your favor.** An example is React components which are often complicated to test. But you can make a design decision to move **all** business logic out of components and into Redux reducers, and by doing that the need to test the components _at all_ becomes much less, since their size relative to the codebase has reduced. You can test the Redux functions instead. They’re just plain functions, so they should be easier.
 * **When you’re experimenting**. Many applications don’t need quality right away, but _do_ need a period of discovery where features can be fluid. In this scenario TDD can slow you done, not speed you up.

## But the rules are still VERY important.

A common belief in education is that **experts make bad teachers**. This follows naturally from the Dreyfus model if you think that being intuitive means losing sight of the rules.

This doesn’t mean that **all** experts are bad teachers. Actually they can make great teachers. They just have to put in extra effort to be great, otherwise they might very well suck.

If you’re involved with working with novices, which is typical for the industry today with mixed skill-level teams, then you must be able to switch back into “pure TDD” mode.

## When MUST I use TDD?

So we can now start to see occasions when TDD is ultra-important and should not be skipped. Here are the two that come to my mind:

 * **When you’re teaching TDD novices.** In order to help them learn, you have to show them the rules. Not your cheats!
 * **When you’re pairing with someone you’ve never worked with.** Even if they’re an expert, they will have a different set of cheats and trade-offs from you. So you should fall back to strict TDD. Whenever a situation occurs where either of you are considering cheating, stop and discuss it. If you can’t reach agreement, then use TDD.