The Artima Developer Community
Sponsored Link

Java Community News
Testing Legacy Code

24 replies on 2 pages. Most recent reply: Apr 14, 2006 10:56 AM by Jeff Ratcliff

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 24 replies on 2 pages [ « | 1 2 ]
Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Testing Legacy Code Posted: Apr 7, 2006 6:03 PM
Reply to this message Reply
Advertisement
> Well Isaac, refactorings does not preserve functionality
> by itself, and you need the support from unit tests to do
> exactly that.
>
I would be more general and say that you need to test your changes to make sure they do what you want. If you're adding new functionality, you need to test to make sure the new functionality works as desired and that you didn't break old functionality. Unit tests are one kind of test, but they aren't the only kind.

> How can you prove that nothing was
> broken during refactoring without tests?
>
Prove is a strong word, but I think you're saying how can we be confident we didn't break anything during refactoring without tests. I think even for the simplest most obvious looking changes, we'd better test it. "I'm sure this will work" often turns out to be overconfidence. But once again, it doesn't necessarily require a unit test.

> Of course you can
> do it manually, but then, the costs and dangers of
> refactoring just touched the sky!
>
And I think one should consider the costs and benefits and make decisions using experience and the best information you have at the time. One problem I have with XP is that it seems to suggest you don't think, you always write a unit test first, without doing a cost/benefit analysis. I definitely like TDD, but it is not my religion. It is a tool. If you are facing a legacy system with no unit tests, writing unit tests for the whole thing just so you can be confident you didn't break anything with a bug fix or refactor also has a cost that touches the sky.

Faced with needing to fix a bug in a legacy system that has no tests, and feeling the desire to clean up a bit around where you make the change, I think the best thing to do is write a unit test that fails because of the bug, then fix the bug (verify it with the passing test), make some minor cleanup if you wish, but maybe not just to minimize risk, and then test it by hand.

On the other hand, sometimes it isn't so cheap as just whipping off a unit test. Sometimes to write a unit test, you really need to spend some time thinking about and building a test harness. If the bug fix is urgent, the customer is threatening to go with a competitor's product if they don't get the fix tomorrow, and you think it might take you a few days to figure out how to establish a test harness, then it is much better for the business to forget unit testing altogether, and just make the fix, test it by hand, and ship it off to the customer.

Or, if this legacy code is for a legacy product that's pretty stable, and is being replaced by a different product on a completely different codebase, then maybe you'll judge it isn't worth spending the time needed to figure out and build the test harness at all even if the customer isn't breathing down your neck, that those resources could better be spent elsewhere, such as on the new codebase.

Marc Loxton

Posts: 9
Nickname: spoonchops
Registered: Feb, 2006

Re: Testing Legacy Code Posted: Apr 9, 2006 11:48 PM
Reply to this message Reply
> Dag Blakstad wrote How can you prove that nothing was
> broken during refactoring without tests?

> By proof :-) (Tests don't prove.)

I would argue that "proof" in the purest form doesn't exist in software development. I bet the developer "proved" his code worked before shipping the product in the first instance yet this bug was still found afterwards. If given a well specified use-case for the failing software condition then an appropriate unit test can prove with as much certainty as a manual test in most cases.

As for Bill's comments on TDD I agree with most of what he says. As Engineers we're compelled to consider such factors as budgets, deadlines, administration and in the cases mentioned there is nothing wrong with cutting some corners on our usual practices (usual practices because TTD is a way of thinking and not a set of rules).

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Testing Legacy Code Posted: Apr 11, 2006 6:48 PM
Reply to this message Reply
> It's interesting that this discussion doesn't mention
> requirements. How can you test something if you don't know
> what it is supposed to do? If you reverse-engineer the
> requirements from the code than obviously the code is 100%
> correct.

You can write tests that demonstrate the actual behavior of the system. Often that is the invariant you have to work against when you refactor.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Testing Legacy Code Posted: Apr 11, 2006 7:01 PM
Reply to this message Reply
> If you are facing a legacy system with no unit
> tests, writing unit tests for the whole thing just so you
> can be confident you didn't break anything with a bug fix
> or refactor also has a cost that touches the sky.

I agree. That's why I advise getting tests in place only for areas you are about to change. Go upstream from the change points, find a place to write tests, break dependencies, write the tests, then make the change.

The tough part is breaking dependencies where you need to to write the tests. It is a form of refactoring, but there are a set of very conservative techniques you can use to feel confident that nothing is being broken as you get tests in place. When the tests are in place, it's easier to be more aggressive.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Testing Legacy Code Posted: Apr 12, 2006 11:13 AM
Reply to this message Reply
> > You can break things very easily by editing code, but
> > not by refactoring - that's the point ;-)
>
> This reminds me of my youth when my mother wanted me to
> get a haircut. She said: You don't have to get it cut,
> just "shaped". How can you refactor code without editing
> it?

I'm just being boorish about what we actually mean by refactoring ;-)

imo there's something special about refactoring, something that gives it special value - refactoring preserves behaviour.

When we have a tool that automates refactoring then we don't need additional testing, we refactored therefore behaviour was preserved. The only changes we were allowed to make were changes that preserved behaviour.

Jeff Ratcliff

Posts: 242
Nickname: jr1
Registered: Feb, 2006

Re: Testing Legacy Code Posted: Apr 13, 2006 12:45 PM
Reply to this message Reply
> When we have a tool that automates refactoring then we
> don't need additional testing, we refactored therefore
> behaviour was preserved. The only changes we were allowed
> to make were changes that preserved behaviour.

This assumes that the autorefactoring tool has no bugs and can refactor any code without any possibility of changing the behavior.

It seems to me that it wouldn't be that hard to write code using reflection whose behavior will change with just a change in method names.

This is artifical example perhaps, but it points out that no method of code transformation is entirely behavior-preserving in the general case unless it understands that underlying behavior.

Now we can say that refactoring is behavior-preserving by definition, but in that case I would conclude that there are no autorefactoring tools because they can't meet the absolute requirements of refactoring.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Testing Legacy Code Posted: Apr 13, 2006 10:54 PM
Reply to this message Reply
> It seems to me that it wouldn't be that hard to write code
> using reflection whose behavior will change with just a
> change in method names.
>
> This is artifical example perhaps, but it points out that
> no method of code transformation is entirely
> behavior-preserving in the general case unless it
> understands that underlying behavior.
>
> Now we can say that refactoring is behavior-preserving by
> definition, but in that case I would conclude that there
> are no autorefactoring tools because they can't meet the
> absolute requirements of refactoring.

Previous comments provided other examples of code artefacts which are outside the ken of the "refactoring tool", imo in those situations we don't have a "refactoring tool" - it's broken. ;-)

Jeff Ratcliff

Posts: 242
Nickname: jr1
Registered: Feb, 2006

Re: Testing Legacy Code Posted: Apr 13, 2006 11:53 PM
Reply to this message Reply
> Previous comments provided other examples of code
> artefacts which are outside the ken of the "refactoring
> tool", imo in those situations we don't have a
> "refactoring tool" - it's broken. ;-)

So in my view we either take a less strict interpretation of refactoring that may require retesting or use the strict interpretation of refactoring which is not very useful or interesting in practice.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Testing Legacy Code Posted: Apr 14, 2006 9:52 AM
Reply to this message Reply
> So in my view we either take a less strict interpretation
> of refactoring that may require retesting or use the
> strict interpretation of refactoring which is not very
> useful or interesting in practice.

Did you mean, take a less strict interpretation of refactoring that always requires retesting?

> not very useful or interesting in practice
When software development fits within the limitations of the refactoring tools, we can avoid unnecessary work. YMMV

Jeff Ratcliff

Posts: 242
Nickname: jr1
Registered: Feb, 2006

Re: Testing Legacy Code Posted: Apr 14, 2006 10:56 AM
Reply to this message Reply
> Did you mean, take a less strict interpretation of
> refactoring that always requires retesting?

No, a less strict interpretation of refactoring that allows for the possibility that the transformation process wasn't entirely behavior-preserving. In other words, that the attempt at refactoring has failed. In some cases we may be able to tell that the refactoring was sucessful by inspection or we may have to perform testing to be sure.


> When software development fits within the limitations of
> the refactoring tools, we can avoid unnecessary work. YMMV

My argument is that the restricted set of refactoring that an automated tool can flawlessly perform will often be of little value. For example refactoring a integrated GUI application into a MVC application may improve the design, but I doubt that an automated tool could perform that refactoring entirely on its own. But I agree that YMMV.

Flat View: This topic has 24 replies on 2 pages [ « | 1  2 ]
Topic: Testing Legacy Code Previous Topic   Next Topic Topic: Java Browser Edition?

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use