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

Testing Legacy Code Posted: Apr 5, 2006 8:54 AM
Reply to this message Reply
Summary
In this developerWorks article, author Elliotte Rusty Harold shows you how to develop a test suite for legacy code that's never been tested.
Advertisement
Near the end of the article, Testing legacy code, Elliotte Harold discusses "exploratory" testing in the context of testing legacy code:

Going into a legacy system, you'll often have a good idea of where you need to look: You're having problems with a particular module or package or set of circumstances, and that problem drives your testing. In this case, by all means focus your tests on that one area.

Sometimes you have a very clear and obvious bug. Before you start fixing it, write a test. Then run the test to make sure the test fails. Surprisingly often, however, your first instinct about the cause of a bug is not correct, in which case the test passes. Whether a test fails or not, don't throw it away. It's still valuable for future development. Leave it in your test suite and write another test. Repeat until you find a test that does fail and thus discover the true cause of the bug.

This "exploratory" testing is usually how I think about adding automated tests to legacy code that has none, because usually it isn't economically justifiable to spend a month adding tests to a system that's already working. If you have a bug to fix, however, you can perhaps write a test that fails because of the bug, then fix the bug. The main thrust of this article, however, is to show you how to go about spending time writing tests in general on legacy code:

The good news is that test-driven development isn't just for new code. Even programmers maintaining old systems can profitably write, run, and pass tests. Indeed tests are even more important for legacy systems already in production. Only by testing can you be confident that changes you make to one part of a system will not break another part somewhere else. Sure, you might not have the time or the budget to achieve 100 percent test coverage for a large legacy code base, but even less-than-perfect coverage reduces the risk of failure, speeds up development, and produces more robust code.

What's your opinion on the merits of testing legacy code? When does the payback justify the time spent writing the tests?


Nicolas Nombela

Posts: 17
Nickname: nnombela
Registered: Feb, 2005

Re: Testing Legacy Code Posted: Apr 5, 2006 10:03 AM
Reply to this message Reply
Testing unknown code is hard. Wouldn't it be better, easier and quicker to start refactoring the code (I make the assumption that a code that doesn't have a test suite is probably not well structured), and then make the test code for the refactored instead of the original code?

V.H.Indukumar

Posts: 28
Nickname: vhi
Registered: Apr, 2005

Re: Testing Legacy Code Posted: Apr 5, 2006 10:19 AM
Reply to this message Reply
The problem with refactoring a code that you don't understand well without having proper test suite is that there is a danger of introducing new bugs or losing functionalities. It is always better to have a test suite that specifies how the code should behave and then refactor.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Testing Legacy Code Posted: Apr 5, 2006 10:47 AM
Reply to this message Reply
The problem with refactoring a code that you don't understand well without having proper test suite is that there is a danger of introducing new bugs or losing functionalities.
I'm curious how refactoring could introduce bugs or lose functionality - isn't refactoring by definition a behavior preserving transformation.

Dag Blakstad

Posts: 7
Nickname: dag
Registered: Aug, 2003

Re: Testing Legacy Code Posted: Apr 5, 2006 11:08 AM
Reply to this message Reply
> The problem with refactoring a code that you don't
> understand well without having proper test suite is that
> there is a danger of introducing new bugs or losing
> functionalities.

> I'm curious how refactoring could introduce bugs or lose
> functionality - isn't refactoring by definition a
> behavior preserving transformation
.


The two practices TDD and Refactoring belongs together. To be able to do refactoring you need to know that you don't break any existing code. That is why you must combine these practices. Refactoring code with unknown functionality without tests is like driving around in a unfamiliar city, without a map, looking for the hospital. You may be lucky finding a sign telling you where to go, but may you also waste a lot of time.
Another example would be a doctor treating a patient without examining the person first. That could be really disastrous.

Creating tests for unfamiliar code helps you get familiar with it, before you start changing anything, and will make you much more confident that nothing gets broken or accidentially lost during refactoring.

A promising Java tool is available here: https://testplayer.dev.java.net/

Dag

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Testing Legacy Code Posted: Apr 5, 2006 11:12 AM
Reply to this message Reply
> Testing unknown code is hard. Wouldn't it be better,
> easier and quicker to start refactoring the code (I make
> the assumption that a code that doesn't have a test suite
> is probably not well structured), and then make the test
> code for the refactored instead of the original code?

I don't agree with the assumption that if code doesn't have a test suite it probably isn't well structured. Those are two independent things. I have found that test-driven development helps encourage well factored code, but that doesn't imply that if you don't have an automated test, the code is therefore messy.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Testing Legacy Code Posted: Apr 5, 2006 11:17 AM
Reply to this message Reply
> The problem with refactoring a code that you don't
> understand well without having proper test suite is that
> there is a danger of introducing new bugs or losing
> functionalities. It is always better to have a test suite
> that specifies how the code should behave and then
> refactor.


Well, regardless of whether you have an automated test or not, I think you should test your changes by hand. What comprehensive automated tests give you is notification of things you've broken that you might not have caught with a hand test. That's really nice, but not required before making a change.

Any time you change code there's a risk you can "introduce new bugs or lose functionalities," as you put it, so you'd better test afterwords to make sure you didn't do that. It doesn't mean that you shouldn't touch the code, just that you have to check your work.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Testing Legacy Code Posted: Apr 5, 2006 4:29 PM
Reply to this message Reply
Dag Blakstad wrote To be able to do refactoring you need to know that you don't break any existing code.
Once again, refactoring by definition is a behavior preserving transformation.

When we use a refactoring provided by Eclipse or IDEAJ, external behaviour and functionality is the same after refactoring as it was before.

When we edit code by hand and claim we are refactoring, then we must test to confirm that the external behaviour and functionality have in fact been preserved.

Nicolas Nombela

Posts: 17
Nickname: nnombela
Registered: Feb, 2005

Re: Testing Legacy Code Posted: Apr 6, 2006 12:26 AM
Reply to this message Reply
Refactoring and testing go hand in hand. I don't agree with the statement that refactoring the code may introduce MORE bugs. Instead you get to know the code better, get more confident if you have to make behavior changes, makes the code more readable and easier to find unknown bugs, and also make it easier to write correct test code.

Michael Stover

Posts: 28
Nickname: mstover
Registered: Jul, 2005

Re: Testing Legacy Code Posted: Apr 6, 2006 6:20 AM
Reply to this message Reply
> Dag Blakstad wrote To be able to do refactoring you
> need to know that you don't break any existing code.

> Once again, refactoring by definition is a behavior
> preserving transformation.
>
> When we use a refactoring provided by Eclipse or IDEAJ,
> external behaviour and functionality is the same after
> refactoring as it was before.

But you may have changed API's, names of methods, locations of methods, input parameters etc. Eclipse and IDEAJ can only update referenced code they know about - which may or may not include groovy scripts, jpython scripts, jsp's, velocity templates, unknown uses of reflection, automatic wiring defined in xml files, etc etc etc.

You can break things very easily with the simplest of refactorings.

Roland Pibinger

Posts: 93
Nickname: rp123
Registered: Jan, 2006

Re: Testing Legacy Code Posted: Apr 6, 2006 12:33 PM
Reply to this message Reply
Michael Feathers' "Working Effectively with Legacy Code" also deals with testing legacy code. See e.g. chapter "I Can’t Get This Class into a Test Harness", available online as sample chapter: http://www.objectmentor.com/resources/bookstore/books/welc/

Dag Blakstad

Posts: 7
Nickname: dag
Registered: Aug, 2003

Re: Testing Legacy Code Posted: Apr 6, 2006 1:00 PM
Reply to this message Reply
Well Isaac, refactorings does not preserve functionality by itself, and you need the support from unit tests to do exactly that. How can you prove that nothing was broken during refactoring without tests? Of course you can do it manually, but then, the costs and dangers of refactoring just touched the sky!

Dag

Jeff Ratcliff

Posts: 242
Nickname: jr1
Registered: Feb, 2006

Re: Testing Legacy Code Posted: Apr 7, 2006 12:34 AM
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.

It's also interesting to me how functional testing has been reclassified as "customer testing" even though it is been used sucessfully for non-customer testing for many years.

It seems to me that if you have to test legacy code that you're not familiar with and if you actually have requirements (politically incorrect these days, I know), functional testing will get you there much faster than retrofitting unit testing into the code.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Testing Legacy Code Posted: Apr 7, 2006 10:21 AM
Reply to this message Reply
Michael Stover wrote Eclipse and IDEAJ can only update referenced code they know about - which may or may not include groovy scripts, jpython scripts, jsp's, velocity templates, unknown uses of reflection, automatic wiring defined in xml files, etc etc etc.
Yes, refactoring requires complete knowledge of all dependencies, without that knowledge we just have automated code-editing - we don't have a refactoring tool.

Michael Stover wrote You can break things very easily with the simplest of refactorings.
You can break things very easily by editing code, but not by refactoring - that's the point ;-)

Dag Blakstad wrote How can you prove that nothing was broken during refactoring without tests?
By proof :-) (Tests don't prove.)

Jeff Ratcliff

Posts: 242
Nickname: jr1
Registered: Feb, 2006

Re: Testing Legacy Code Posted: Apr 7, 2006 11:35 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?

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