Jason McCreary has a post with an interesting perspective about code refactoring and what it means to refactor. He suggests that just changing code isn't refactoring and that it's more about changes in the observable behavior.
There was a good discussion on Twitter yesterday regarding a code contribution to the Laravel framework. It ended with some good questions about the distinctions between “refactoring” vs “changing” code.
While I want to focus on these distinctions, let’s first focus on the code change.
He gives an example of some code from the suggested change that reduced the number of lines in a
before function call that still satisfied the requirements defined by the unit tests. He suggests that, while this change allowed the method to work as expected, it was more of a "change" than a "refactor". He suggests that because the code internal to the method changed that the "observable behavior" changed because of a special case with the return value. Existing tests didn't catch the change so it was assumed the refactor was successful even when it wasn't. Adding this test and fixing the issue then resulted in a true refactor and not just a change.
Given the symbiotic relationship between refactoring and testing, some consider the tests to be the requirements. So if all tests pass, you met the requirements. I think that’s a slippery slope. For me, the definition of “refactoring” again provides the answer through its own question - did we change the observable behavior?