Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactoring for Testability on an existing system

I've joined a team that works on a product. This product has been around for ~5 years or so, and uses ASP.NET WebForms. Its original architecture has faded over time, and things have become relatively disorganized throughout the solution. It's by no means terrible, but definitely can use some work; you all know what I mean.

I've been performing some refactorings since coming on to the project team about 6 months ago. Some of those refactorings are simple, Extract Method, Pull Method Up, etc. Some of the refactorings are more structural. The latter changes make me nervous as there isn't a comprehensive suite of unit tests to accompany every component.

The whole team is on board for the need to make structural changes through refactoring, but our Project Manager has expressed some concerns that we don't have adequate tests to make refactorings with the confidence that we aren't introducing regression bugs into the system. He would like us to write more tests first (against the existing architecture), then perform the refactorings. My argument is that the system's class structure is too tightly coupled to write adequate tests, and that using a more Test Driven approach while we perform our refactorings may be better. What I mean by this is not writing tests against the existing components, but writing tests for specific functional requirements, then refactoring existing code to meet those requirements. This will allow us to write tests that will probably have more longevity in the system, rather than writing a bunch of 'throw away' tests.

Does anyone have any experience as to what the best course of action is? I have my own thoughts, but would like to hear some input from the community.

like image 221
steve_c Avatar asked Aug 21 '08 15:08

steve_c


People also ask

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.

What is the best approach to ensure that code doesn't break existing functionality?

By refactoring and using TDD, you can implement a principle that Kent Beck calls "You're Not Going to Need It." You can defer any implementation of code that doesn't directly relate to the functionality that you're currently building until you have a test—drawn from a user story—to specifically test that functionality.

Why is testing important for refactoring?

Testers ensure the proper testing of the functionality of the application. As the test written by testers is code too, it is necessary for testers to use refactoring technique to simplify their complex code. The test code written by testers should be easily understandable and readable.

How would you ensure the new commits won't break the existing system?

Don't Break Builds Another version control best practice is to avoid breaking builds by doing complete commits. Provide test cases and at least stubs for new APIs. This ensures every commit is usable by any other member in the team without breaking their build. A complete commit is easier to propagate between branches.


1 Answers

Your PM's concerns are valid - make sure you get your system under test before making any major refactorings.

I would strongly recommend getting a copy of Michael Feather's book Working Effectively With Legacy Code (by "Legacy Code" Feathers means any system that isn't adequately covered by unit tests). This is chock full of good ideas for how to break down those couplings and dependencies you speak of, in a safe manner that won't risk introducing regression bugs.

Good luck with the refactoring programme; in my experience it's an enjoyable and cathartic process from which you can learn a lot.

like image 163
Ian Nelson Avatar answered Nov 15 '22 01:11

Ian Nelson