TDD: It’s Not That Simple
TDD is pretty simple right? Obey the red-green-refactor step-by-step and you’re on your way to glorious, non-legacy code.
It’s really easy to explain. The rules are easy to follow. Why then so few people actually do it, and when they do, so few actually do it well?
In my talk at Lean Agile Scotland 2015, “Rebooting ALM“, I talked about why people crave processes and tools, although this contradicts the first Agile Manifesto tenet. I also talked about how Application Life-cycle Management tools hide real-life complexity, by pertaining to make things simple. However, they usually fail us.
I think reducing TDD to the red-green-refactor formula falls into the same trap. We don’t get the glory, and we’re left with the legacy.
In Cynefin terms, we apply TDD in the complex domain – where the code and design have not been created yet. There is no visible causation between the prescriptive rules and the outcome. Yet the rules seem like a “good practice”, that should be applied in the complicated domain, where there is a high-probability causation. Apply a recipe under the wrong context, and you can understand why things go bad.
I’ve already talked about how TDD will not necessary lead you to better design. Notice that having good design skills don’t appear in the formula? The invisible assumption that you have them is definitely there. In fact it serves as an invisible warning: Continue at your own peril. Too bad it’s invisible.
From my experience, the assumption is correct. Without good design skills, using TDD leads to bad code and bad tests. The promise of consistently maintainable code is not kept. After a while, developers get the message, and drop it.
The funny thing is that doing it “right” has much less to do with the formula, than with continuous introspection and learning. If you do it “right”, you’ll get better as you learn from the feedback. Doing it “wrong”, by just following the formula will probably lead you to abandon it.
TDD is a set of skills. Skills are improved by practice, seeking feedback, and adopting our behavior based on them. If we have enough understanding and good goal, practice does goes a long way to make perfect.
If, however, we just follow a recipe, success is hardly guaranteed. It’s like training in the gym, without understanding how muscles develop.
It may work for a while, but will become painful and may lead to long term negative affects.
Pavneet Singh Saund · February 7, 2016 at 10:37 am
Thanks for sharing your thoughts on this Gil.
I love how you compared applying TDD within the context of the Cynefin framework and how a typical Complicated domain may not be the best place to apply it. I guess there are certain sub-domains / bounded contexts within Chaotic/Complicated domains that may be classified as Complex/Obvious where causation and result can be correlated and thus be more applicable to TDD.
I’ve attempted to frame my thoughts on this matter myself, which I would appreciate your view on. https://pavsaund.wordpress.com/2016/02/04/making-the-right-thing-work-before-making-it-work-right/.