Test Every Refactoring

You applied RefactorInVerySmallSteps. You don't want to find out after 37 refactorings that somewhere around the 21st you made a mistake. It is probably hard to go back without throwing all your changes away.

Therefore, test every refactoring. UnitTests are great for this. Also, if you added or moved code, make sure that it gets called. One way to do this is to introduce deliberate errors in the new code, so that the tests will fail. Another option is to set a breakpoint in the new code and see whether it is reached by the test code.


Run all the tests after the fewest possible edits - say 10 at the most. If you are not adding features, expect every test run to pass, and Undo your last edits if they don't.

That rule forces you to continuously return the code to a passing state. That passing state forces your designs to relentlessly decouple.


Also, of course, make sure you can roll back the refactoring without too much work in case the tests do fail. That is, at least for larger changes, have a backup copy of the state of your program before the refactoring (if your environment doesn't provide this automatically). --FalkBruegmann

This comment was transformed into BodyguardPattern.


I usually first comment out the code to be removed, and only really delete it at the end of a RefactoringEpisode?. This only gives problems if the tests weren't good enough, the refactoring really broke something, and I find out too late. This approach works best in an environment where you have syntax highlighting, so that you can see immediately what is code and what isn't. --MarnixKlooster

I think this depends on your environment. Using ENVY, either Smalltalk or Java, I just delete the suspicious code. "Load Previous Edition" gives me a quick way back. --KentBeck


I'm finding that if I TestEveryRefactoring, and then compare outputs after the tests pass, this technique helps me tighten up my UnitTests. (Though maybe this means I'm a little too lazy about writing them at first.)

For example: I'm currently writing a large report-generating program that spits out CSV files. So when I refactor, I:

Occasionally, the outputs will vary in a way that I don't like, which teaches me two things. 1. that my refactoring broke something, and 2. my UnitTests weren't rigorous enough to catch it. So before fixing the refactoring, I fix the UnitTest, or add another UnitTest to catch a similar bug next time around. -- francis
EditText of this page (last edited July 8, 2004)
FindPage by browsing or searching

This page mirrored in WikiPagesAboutRefactoring as of July 17, 2004