In this lexical scope, TDD by example is referring to this book1, available on Amazon
The TDD cycle
Altough Kent Beck in his book Test-Driven Development by example explains in “Part I: the money example”2 that one should
quickly add a test;
run all the tests and see the new one fail […]
Kent Beck
Implying that the TDD cycle starts with the red. Later on he explains that the cycle continues with green and refactor and back to red.
But I’ve been hearing for a while that there’re some useful refactors to be done before introducing new code. Rings in my head but the only example I have is Xavi Gost’s “La economía del refactoring3”
Refactoring
Let’s take a look at the definition of refactor (found here):
[Refactoring] is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.
Martin Fowler
I’ve found some info on stackoverflow about the subject. The currently accepted answer points out some interesting comments:
- Do not refactor on red. Always a good reminder
- If you are refactoring for introducing a feature, how much refactor is enough? This is speculative development, possibly taking much time from needed development
The last point is the one that interests me the most:
- Your refactoring might not be where you’re going to introduce new production code4 (spatial caché)
- You might end up introducing features after a few hours/days of refactoring, therefore losing focus on the refactor you did and why (local caché)
- Given that I’ve already “cleaned up” this, I could also go somewhere else (slippery slope). Heard from Xavi Gost at the CAS2014 at his talk La economía del refactoring
No está justificado hacer cambios fuera de la rebanada.
Roughly translated to “It’s not justified to change outside the bread slice”, as Xavi was referring to software as sliced bread instead of layers, vertical rather than horizontal
Should you do it?
- Doing it would be a good thing, as long as you know in advance what will be affected by the next feature.
- It can allow for less refactoring at the end of the cycle. This is not about duplication but refactoring to patterns. There might be a gain in refactoring to a pattern before introducing another feature. An example might be adding a new strategy when it’s currently coded as if-then-else
- The last responsible moment might be before or after introducing the feature. You decide.
- Work less as there’s no need for adding new cases to old structures and then simplifying
Should you not do it?
- Foreseeing the future is difficult, therefore you might end with unused development, as it is speculating
- Related to the last point, you might end refactoring in the wrong places. There’s no current business value to it.
- Not useful on first round of a new feature, you can use a lambda transition to the red again. But then, this is not a general pattern, only applicable to a big percent of cases.
Conclusions
Short answer: it mainly depends on your environment:
- You: experience, common sense (sadly) —another post coming—, benefit/time-wasted ratio
- Your project: how tight are deadlines, how critical that code is, the team’s pressure
Long answer: Yes, as long as:
- You realize there is a fine line between fixing code and rewriting code (Egoless programming #4). Don’t be a lone enforcer
- Strictly follow the boy scout rule but only around your campfire, not outside of it.
- You know your domain, pitfalls and team well
- You want to test this hypothesis and post an answer
Sources
- La economía del refactoring, Xavi Gost
- Test-Driven Development by example, Kent Beck
- Refactoring.com, Martin Fowler