Alex Rivera | Logout

How do I ensure that I don't break the test code when I refactor it?

Asked 2011-12-19T21:57:48.997
10

Code evolves, and as it does, it also decays if not pruned, a bit like a garden in that respect. Pruning mean refactoring to make it fulfill its evolving purpose.

Refactoring is much safer if we have a good unit test coverage. Test-driven development forces us to write the test code first, before the production code. Hence, we can't test the implementation, because there isn't any. This makes it much easier to refactor the production code.

The TDD cycle is something like this: write a test, test fails, write production code until the test succeeds, refactor the code.

But from what I've seen, people refactor the production code, but not the test code. As test code decays, the production code will go stale and then everything goes downhill. Therefore, I think it is necessary to refactor test code.

Here's the problem: How do you ensure that you don't break the test code when you refactor it?

(I've done one approach, https://thecomsci.wordpress.com/2011/12/19/double-dabble/, but I think there might be a better way.)

Apparently there's a book, http://www.amazon.com/dp/0131495054, which I haven't read yet.

There's also a Wiki page about this, http://c2.com/cgi/wiki?RefactoringTestCode, which doesn't have a solution.

Edit
Report

1 Answer

2

I think you should not change your test code.

Why? In TDD, you define a interface for a class. This interface contains methods that are defined with a certain set of functionality.The requirements / design.

First: These requirements do not change while refactoring your production code. Refactoring means: changing/cleaning the code without changing the functionality.
Second: The test checks a certain set of functionality, this set stays the same.

Conclusion: Refactoring test and refactoring your production code are two different things.

Tip:When write your tests, write clean code. Make small tests. Which really test one piece of the functionality.

But "Your design changes because of unforeseen changes to the requirements". This may lead or may not lead to changes in the interface.
When your requirements change, your tests must change. This is not avoidable.
You have to keep in mind that this is a new TDD cycle. First test the new functionality and remove the old functionality tests. Then implement the new design.

To make this work properly, you need clean and small tests. Example:

MethodOne does: changeA and changeB

Don't put this in 1 unit test, but make a test class with 2 unit tests.
Both execute MethodOne, but they check for other results (changeA, changeB).

When the specification of changeA changes, you only need to rewrite 1 unit method.
When MethodOne gets a new specification changeC: Add a unit test.

With the above example your tests will be more agile and easier to change.

Summary:

  • Dont refactor your tests, when refactoring your production code.
  • Write clean and agile tests.

Hopes this helps. Good luck with it.

@disclaimer: I do not want your money if this makes you rich

answered 2011-12-19T23:29:49.173

Your Answer