Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate that a Refactoring is equal to original code

I'm working with legacy java code, without any Unit-Tests. Many classes need to be refactored in order to work with the project.

Many refactorings can be done with eclipse, and am I doing some by hand. After some refactoring I review the diff to cvs-HEAD, but i can't really feel certain that everything is 100% correct.

The Question: How can I validate a refactoring, that is mathematical identical to the previous version? I wish there were a tool, but i also accept "basic human algorithms" as solutions.

I know, "run your JUnit-Tests" is the best answer, but sadly, there aren't any in my project.

Thank you!

like image 203
Synox Avatar asked Jan 26 '10 08:01

Synox


People also ask

What is the value of refactoring code?

The goal of refactoring is to improve internal code by making many small changes without altering the code's external behavior. Computer programmers and software developers refactor code to improve the design, structure and implementation of software. Refactoring improves code readability and reduces complexities.

What is the most common cause of refactoring problems?

The most common cause of refactoring problems is not in the code -- it's a lack of proper tools. Refactoring nearly always includes renaming variables and methods, changing method signatures, and moving things around. Trying to make all these changes by hand can easily lead to disaster.

What is the relationship between refactoring and testing?

The test-first strategy emphasizes that test cases are designed before system implementation to keep the correctness of artifacts during software development; whereas refactoring is the removal of “bad smell” code for improving quality without changing its semantics.


2 Answers

In "TDD By Example" there is a specific section that talks about it. The problem is that you need unit tests to refactor, but a complicated code is usually non-testable. Thus, you want to refactor to make it testable. Cycle.

Therefore the best strategy is as follows:

Do tiny refactoring steps. When the steps are small it is easier for a human to make sure the overall behavior is intact. Choose only refactorings that increase testability. This is your immediate goal. Don't think about supporting future functionality (or anything fancy like that). Just think about "how can I make it possible for a unit test to test this method/class".

As soon as a method/class becomes testable, write unit tests for it.

Repeating this process will gradually get you to a position where you have tests and thus you can refactor more aggressively. Usually, this process is shorter than one would expect.

like image 195
Itay Maman Avatar answered Oct 14 '22 14:10

Itay Maman


You're going down a slippery slope if you think you can detect that by eye-balling the program. And as one of the other responders already said, the question of whether two programs are equal is undecidable (by a turing machine).

If you don't have unit tests, I suggest you at least set up a regression test harness. Take a snapshot of some input and some output version 1 of the program takes/produces, run it through version two and make sure the results are the same.

If it's a GUI, I hope it has MVC separation so you can test the model separately, otherwise you may be stuck.

like image 40
xcut Avatar answered Oct 14 '22 12:10

xcut