Testing – Writing Tests for Code with Unclear Purpose

refactoringtesting

I recently completed a black-box refactoring. I am unable to check it in, because I can't work out how to test it.

At a high level, I have a class whose initialization involves grabbing values from some class B. If class B is "empty", it generates some sensible defaults. I extracted this part to a method that initializes class B to those same defaults.

I have yet to work out the purpose/context of either class, or how they would be used. So I can't initialize the object from an empty class B and check that it has the right values/does the right thing.

My best idea is to run the original code, hardcode in the results of public methods depending on the initialized members, and test the new code against that. I can't quite articulate why I feel vaguely uncomfortable with this idea.

Is there a better attack here?

Best Answer

You are doing fine!

Creating automated regression tests is often the best thing you can do for making a component refactorable. It may be surprising, but such tests can often be written without the full understanding of what the component does internally, as long as you understand the input and output "interfaces" (in the general meaning of that word). We did this several times in the past for full-blown legacy applications, not just classes, and it often helped us to avoid breaking things we did not fully understand.

However, you should have enough test data and make sure you have a firm understanding what the software does from the viewpoint of a user of that component, otherwise you risk omitting important test cases.

It is IMHO a good idea to implement your automated tests before you start refactoring, not afterwards, so you can do the refactoring in small steps and verify each step. The refactoring itself should make the code more readable, so it helps you to increase your understanding of the internals bit by bit. So the order steps in this process is

  1. get understanding of the code "from outside",
  2. write regression tests,
  3. refactor, which leads to better understanding of the internals of the code
Related Topic