TDD Pro-Tip: TDD depends heavily on a view that accepts and even values iteration.
TDD is an I&I style of work: iteration and increment are both involved. Nearly everyone gets “increment”: an increment is an improvement, an enhancement, a detectable step forward in value.
Each increment is a pass over the code, during which we add to its function. TDD noobs take “increment”, then, to mean “add a passing test”. On the one hand, that’s great. On the other hand, that’s not the whole story, not by a lot. Iterations are a superset of increments. Each increment is an iteration, but each iteration may or may not be an increment. The challenge a strong geek faces when she embarks on TDD is to learn how/why we take passes over the code – iterations – that don’t add new function.
I tend, and I think most skilled TDD’ers would agree, to take many very small passes over my code, and the majority of these are usually not increments. They add no new test, let alone adding the function that would pass that test.
What sorts of things do I do in those passes? Well, nearly any of the tiny steps described in Fowler’s Refactoring. They could be renames, or rearrangement of variables, they could be signature changes, constant declarations, extracting a method or a class or an interface.
A newcomer to TDD is quite likely to be mystified by such passes: why change the code if it doesn’t add function to do so? Their complaint is that such passes do not add value, because they add neither function nor test. They see it like this: I am a professional geek, and my whole job is changing code to add user-detectable value to it. Anything I do that isn’t adding that value must be bad.
So where’s the disconnect? I am in fact a professional geek, and my job is changing code to add user-detectable value, so why would I change code and not be adding that user-detectable value?
The answer isn’t mystical. I take many passes over my code without adding a test because I am enabling some optimal degree of changeability in that code.
Code that is easier to change can be changed to add user-detectable value more quickly than code that is harder to change. I take non-increment passes in order to bring code that already passes its tests up to a level of changeability that will make it easier to add more value. It really is just that simple, not rocket science but basic efficiency: people make this kind of decision every day, where they enhance their performance by doing things that are not themselves performing.
If I change out of my galoshes and in to my tennis shoes, I’m preparing to move faster. Sure, I could run the race in my galoshes. Sure, it will take me a few seconds to take them off. But I’m betting that the cost of changing the shoes will be more than made up during the race. And there’s the real challenge: learning when that shoe-changing bet will pay off, and when it won’t. Because let’s be honest, there are plenty of times when a bet like that does not work out. It is a matter of judgment, and we gain that judgment through experience.
The body of skills that a TDD olb has includes a whole lot of that experience and judgment. I can tell you that it took me years and years to build that up.
Over and over again through nearly 20 years of TDD, I have been just sure I’d reached a place where the shoe-changing bet wasn’t worth it. Over and over again I turned out to be mistaken.
So, the advice from this tip: take passes over your code without adding increments of new test/function. Use those passes to enhance changeability.
To build your sense of whether a given shoe-changing bet will be worth it, try this: go too far. Don’t stop taking non-increment iterations at your first stopping point. Instead, take three extra ones. Each time, change the code, pass the tests again, and push.
Learn the iteration part of I&I. Learn to change code that works even after it works. Develop a sense of how to enhance changeability. Experience how much better it is to change easily changed code.
I think you can learn all this much more quickly than most of your TDD olbs like me did. :)
Have fun, and have a strange Friday!