Beta
×

Welcome to the Slashdot Beta site -- learn more here. Use the link in the footer or click here to return to the Classic version of Slashdot.

Thank you!

Before you choose to head back to the Classic look of the site, we'd appreciate it if you share your thoughts on the Beta; your feedback is what drives our ongoing development.

Beta is different and we value you taking the time to try it out. Please take a look at the changes we've made in Beta and  learn more about it. Thanks for reading, and for making the site better!

Working Effectively with Legacy Code

samzenpus posted more than 5 years ago | from the read-all-about-it dept.

Programming 208

Merlin42 writes "I recently took a Test-Driven-Development (TDD) training course and the teacher recommended that I read "Working Effectively with Legacy Code" by Michael Feathers. First things first, a note about the title. Feathers defines "Legacy Code" a bit different than you may expect, especially if you are not into the XP/Agile/TDD world. I have heard (and used) a number of definitions for "legacy code" over the years. Most of these definitions have to do with code that is old, inherited, difficult to maintain, or interfaces with other 'legacy' hardware/software. Feathers' definition is 'code without tests.' For those not into TDD this may seem odd, but in the TDD world, tests are what make code easy to maintain. When good unit tests are in place, then code can be changed at will and the tests will tell automatically you if you broke anything." Read on for the rest of Kevin's review.Overall this is definitely an interesting read, and useful to anyone who has ever yelled "FSCKing LEGACY code!" It will be most useful to someone who already has some appreciation for TDD and wants to use it to 'pay down the technical debt' in a legacy code project. In my opinion adding unit tests (a sort of retroactive TDD) is the best ... err ... most effective approach for getting a legacy code project into a more malleable state.

One caveat is that most of the book is focused on working with object oriented programming languages. There is some coverage of techniques for procedural languages (mainly C), but this is not the main focus of the book. In a way this is unfortunate, since there is a lot of really useful C code out there gathering dust. But in the book he states that "the number of things you can do to introduce unit tests in procedural languages is pretty small." Unfortunately I would have to agree with him on this point.

One of the greatest things about this book is that it is written by someone who has worked with a lot of legacy code, and there are numerous real world anecdotes sprinkled throughout the text that really serve to help drive the points home. The code examples are plentiful, but not verbose. They all look like real code you might find lurking in a dark corner at work, not some fanciful made up snippet.

The high level goal of the book is show you how to write good unit tests for code that wasn't designed with unit tests in mind. The first step for writing unit tests is getting individual classes or functions into a test harness where you can apply known inputs, and check the outputs or behavior. To do this you need to break dependencies in the original code. The bulk of the book is dedicated to looking at different approaches to breaking dependencies.

Much of the book is organized like a FAQ. There are chapter titles like: "I Need to Make a Change. What Methods Should I Test?" and "My Project Is Not Object Oriented. How Do I Make Safe Changes?". This organization makes the book work a bit better as reference than as learning material. After the first few chapters there is very little flow to the book. Each chapter tends to stand as an independent look into a particular problem common in legacy code. As a result, you can read the table of contents and usually skip to a self-contained chapter that will help with the problem at hand.

The final chapter of the book is a listing of all the refactoring techniques used throughout the rest of book. So if you have a particular dependency-breaking technique in mind, you can skip straight to the description of the technique you want to use. This can be quite helpful when you need to perform a refactoring before you can get your code into a test harness. The descriptions are straightforward and provide a little checklist at the end that will help you make sure you didn't miss anything.

In conclusion I would definitely recommend this book to a colleague who is trying to introduce unit tests into code that was not designed with testing in mind. In fact I have already lent the book to several people at work, most of whom have bought their own copy.

You can purchase Working Effectively with Legacy Code from amazon.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.

cancel ×

208 comments

Sorry! There are no comments related to the filter you selected.

Not needed (5, Funny)

eln (21727) | more than 5 years ago | (#25194819)

This book is a waste of paper. Everyone knows the proper way to deal with legacy code:

1.) Spend 2 weeks looking at code you don't understand.
2.) Loudly complain about the poor quality of the code, particularly algorithms that you don't understand.
3.) Make derogatory comments about the previous developers. Be sure to paint them as monosyllabic imbeciles who probably got dropped on their heads multiple times as children.
4.) Make minor changes to the code. If they blow up in your face, blame the previous developers for their poor grasp of basic programming practices. Make references to the previous programmers' relationship with their mothers.
5.) Delete the whole thing and start from scratch.
6.) 18 months of fumbling around later, realize that the previous code may have been better than you gave it credit for.
7.) Deny this.
8.) Release cobbled-together mess that lacks half the features of the previous codebase and features twice the bugs.
9.) Get job elsewhere.
10.) Company hires new programmer who starts the process over at step 1.

Re:Not needed (4, Insightful)

jellomizer (103300) | more than 5 years ago | (#25194863)

You work at GE right?

Re:Not needed (1)

JazzyMusicMan (1012801) | more than 5 years ago | (#25194891)

If I had points, I'd mod you up, thats exactly how I've seen it.

If it compiles... (4, Funny)

blindd0t (855876) | more than 5 years ago | (#25195005)

...release it. ;-)

Re:If it compiles... (3, Funny)

morgan_greywolf (835522) | more than 5 years ago | (#25195471)

Damn it! I told you not to go around giving out our release process! That's company-proprietary information! *throws chair* You're fired! I'm gonna fscking KILL blindd0t!

-- Steve Ballmer

lol (1)

JeanBaptiste (537955) | more than 5 years ago | (#25195051)

I'm 2 months into my current job of re-writing stuff someone else did. That's spot on.

Re:Not needed (2, Funny)

Fizzl (209397) | more than 5 years ago | (#25195079)

Now that the statute of limitations has run its course, I can safely admit that this sounds really much like my first "professional" project. Too much responsibility for the inexperienced.

Re:Not needed (4, Insightful)

jellomizer (103300) | more than 5 years ago | (#25195105)

I have goten you sarcasm, however I feel some people may miss it, so I will comment on these ideas as if you were serious, as this is actually more like real life then most people want to admit.

1. Trying to analysise the code is a lot of extra work not needed as you can take it for granted that it works correcly and you just need to focus on what doesn't. For most apps a quick search for the button or menu item that is causing the problem will allow you to trace you way to the module and the area that needs to be fixed.

2., 3. and part of 4. Remember people are people. I bet you even write some bad code from time to time. Either you are really tired, under a deadline, or had to work around an other bug that may have been long since fixed, or make the code so optimized that it is unmaintainable. We all do it, most of us won't admit it. So remember that when you are about to critize someones elses code. As well you need to reference the code quality to the time it was made. Look at code in the 1980's it was usually written by people with out Computer Science Degrees, so there will be Goto and the like.

4. Making minor changes when possible is a good method. However if it blows up then you will need to make a larger change... For legacy apps your job isn't as much fixing a bug, but the user of the application has a different process that you need to adjust the computer to account for. The process may have worked for 20 years, and it worked. But it changed sometimes you can get away with a little tweak but sometimes it requires more.

5., 6. Starting from scratch could kill the company. Or be way to expensive. It has been working for 20 years and just needs some minor tweaks, yes maintaining it takes a bit more work then before but it could cost millions (not just programming time, but change management, training, research, bug fixes, missed area....) vs. Paying some guys $100k a year (taking decades to recover the cost of the inital effort)

7. If you admit to the failure you may be able to get the legacy back and running, you may still have a job, although you may get some angry bosses for a while. However you made a mistake it is better to admit it then go down the path of distruction.

8. If you did go threw the full rewrite process you should have put more effors in specing it out, and giving a clearer quote. And accounted for bugs to be fixed.

9. If you messed up to much, sometimes getting a new job is not that easy. Your reputation can spread.

10. Managers should have learned from the mistake and not allowed the new developer to do the same things.
 

Re:Not needed (1)

hairyfeet (841228) | more than 5 years ago | (#25195547)

Wow,must be nice working in some big place where all that applies. Try walking into a SMB to do what you think is a simple hardware upgrade and maybe streamline the network a little and have them go "OMG! Thank God you're here! Our mission critical app is dying and we have all our inventories and payroll tied to it!" and it turns out to be some God awful POS VB3 app written by some guy named Chuck that worked there ages ago on a wheezing and ready to croak any second old NT box.

Of course Chuck never bothered to set up any kind of backup plan and apparently never heard of commenting code and he REALLY liked GOTOs and his code looks like it was written be a drunk in a bad mood. While I have nothing against VB,in fact I think it makes a perfect tool for SMBs if the code is actually well written,trying to figure out the mess that old dumbass Chuck wrote is about as fun as getting hit repeatedly in the head with a sledgehammer. That to me is the real headache of legacy code. When you find some ancient POS program that a company has become way too dependent on that was written as a stopgap by some sloppy coder ages ago. But hopefully you guys don't run into that problem as often,right?

Re:Not needed (1)

zifn4b (1040588) | more than 5 years ago | (#25195635)

5., 6. Starting from scratch could kill the company. Or be way to expensive. It has been working for 20 years and just needs some minor tweaks, yes maintaining it takes a bit more work then before but it could cost millions (not just programming time, but change management, training, research, bug fixes, missed area....) vs. Paying some guys $100k a year (taking decades to recover the cost of the inital effort)

So... they would pay me $100k/year to spend several years working on a new, interesting project. I don't have to work with someone else's crappy code. I can get experience as an architect and add credentials to my resume. I get to potentially have a lot of job security for being the only one that knows how the new system works. If the company goes under, I can use the experience to find an even better job and just blame the company's demise on its bad business model.

I'm really not seeing a problem here. ;)

All tongue and cheek humor aside. The problem here is that what's best for the business's bottom line is quite frequently not what makes developers (or any other employee for that matter) content. If the employees can go work somewhere else that allows them to have creative freedom and be more intellectually stimulated they will. As a result, businesses have to balance these two things because if they can't retain employees, they can't do business and likewise, if they cater to all the demands of their employees, they probably can't do business either.

Re:Not needed (2, Funny)

dcollins (135727) | more than 5 years ago | (#25195935)

"Look at code in the 1980's it was usually written by people with out Computer Science Degrees, so there will be Goto and the like."

Look at my code from yesterday, it was written by a person without a Computer Science degree. There was a Goto and the like.

Re:Not needed (0)

Anonymous Coward | more than 5 years ago | (#25196515)

"1. Trying to analysise the code is a lot of extra work not needed as you can take it for granted that it works correcly and you just need to focus on what doesn't. For most apps a quick search for the button or menu item that is causing the problem will allow you to trace you way to the module and the area that needs to be fixed."

That's all fine and dandy when it's already modular. There are times though when you really need to understand what it does and rewrite it from scratch. Example? I'm rewriting a Perl web app that's been developed over 10 years that has HTML and JavaScript fragments embedded within print statements within the code, along with hard coded "font" tags (yes, it's that old).

There is no easy option to just write tests and get it moved over to an MVC framework.

So, I'm *having* to understand the code so I can document the features and then rewrite the features cleanly.

On the brighter side, it adds a level of job security over the next year or so :)

Re:Not needed (4, Insightful)

Greyfox (87712) | more than 5 years ago | (#25195111)

Good management usually reacts to calls to rewrite with skepticism. Usually (but not always) this is a good thing.

Re:Not needed (1)

The Redster! (874352) | more than 5 years ago | (#25195205)

2a.) Bonus soapbox points for every section with comments like "????" or "I think this works."

Re:Not needed (0)

Anonymous Coward | more than 5 years ago | (#25195449)

11. Inform company that you'll be working from home
12 Hire programer from third world country, at one tenth your salary, to do the work.
13. go on vacation.
14. ???
15. Profit!

Re:Not needed (1)

harry666t (1062422) | more than 5 years ago | (#25195683)

11.) ???
12.) Cthulhu

Whatever (3, Informative)

Anonymous Coward | more than 5 years ago | (#25194857)

Buy Martin Fowler's Refactoring [amazon.com] instead.

Wait a second (3, Funny)

Anonymous Coward | more than 5 years ago | (#25195221)

Did you just refactor his review? BRILLIANT!

Re:Whatever (2, Insightful)

CharlieG (34950) | more than 5 years ago | (#25195717)

No - buy BOTH books, they really do compliment each other

Re:Whatever (1)

Ciarang (967337) | more than 5 years ago | (#25196017)

Surely it would be impossible for the one written first to have foreseen the latter and incorporated praise for it. Or did you mean complement?

Re:Whatever (1)

CharlieG (34950) | more than 5 years ago | (#25196389)

Yes -

Eats, shoots, and leaves

Re:Whatever (2, Insightful)

regeb (157518) | more than 5 years ago | (#25195943)

Buy Martin Fowler's Refactoring [amazon.com] instead.

Remember that in Feathers' book "legacy" means not to have unit tests.

Refactoring starts with the assumption that unit tests are in place. The challenge with legacy code is that very often its current structure makes it impossible to write unit test for it. This book is about techniques of safely transforming untestable code to a form that is testable.

Only after that come actual unit tests, and after that refactoring.

All in all, the two books are complimentary.

Not Object Oriented. How Do I Make Safe Changes? (2, Informative)

DJ Jones (997846) | more than 5 years ago | (#25194879)

Put all your changes in "int main()", use obscure variable names like xspatyc05 or funct123, always use static buffer sizes for any IO operations and under no circumstances should you add comments, it's a waste of time and no one besides you is ever going to have to understand it anyway.

- I <3 Legacy code

Re:Not Object Oriented. How Do I Make Safe Changes (0)

Anonymous Coward | more than 5 years ago | (#25195099)

Pedantic (but this is Slashdot): "int main()" is not one of the valid forms for "main" allowed by the C standard (another the standard does allow for extensions). It is, however, a valid form for C++.

Re:Not Object Oriented. How Do I Make Safe Changes (1)

siride (974284) | more than 5 years ago | (#25195259)

Uhh, yes it is. I can't find a single reference online that indicates otherwise. It most certainly is not the "void main()" travesty.

Re:Not Object Oriented. How Do I Make Safe Changes (0)

Anonymous Coward | more than 5 years ago | (#25196105)

Um, you're a moron. Online??? Yeah, that's authoritative! Check the STANDARD itself! See 5.1.2.2.1 "Program Startup." The only standard forms are "int main(void)" or "int main(int argc, char *argv[])" or equivalent, such as "int main(int argc, char **argv)"

Re:Not Object Oriented. How Do I Make Safe Changes (1, Informative)

mrchaotica (681592) | more than 5 years ago | (#25196421)

Pedantic (but this is Slashdot): "int main()" is not one of the valid forms for "main" allowed by the C standard

...

The only standard forms are "int main(void)"...

"int main()" and "int main(void)" are the same thing, you idiot!

If you're going to be pedantic, at least try not to fuck it up!

Re:Not Object Oriented. How Do I Make Safe Changes (0)

Anonymous Coward | more than 5 years ago | (#25195397)

Every time you write void main(void), God crushes a kitten.

Re:Not Object Oriented. How Do I Make Safe Changes (1)

Mr. Slippery (47854) | more than 5 years ago | (#25195823)

use obscure variable names like xspatyc05 or funct123, always use static buffer sizes for any IO operations and under no circumstances should you add comments, it's a waste of time and no one besides you is ever going to have to understand it anyway.

You used to work for my current employer, didn't you? And a couple (though, thank Goddess, not all) of my previous employers, too...

tests? (-1, Offtopic)

Anonymous Coward | more than 5 years ago | (#25194885)

CmdrTaco got tested for Herpes (turned out it was just anal warts), but slashdot still sucks.

Not exactly... (5, Insightful)

Kindaian (577374) | more than 5 years ago | (#25194893)

The simple passing of all tests doesn't necessarily means that you didn't broke anything.

It means only that you passed the tests.

If the tests don't provide coverage for ALL the business issues that the piece of software is supposed to solve, then you pass the tests, but will have no clue if you broke or not things apart.

Best approach is to evaluate current test procedures and check if they provide enough coverage for at least all user related actions and all the automated actions.

Only after you know that your testing procedures are sound, you can have that assurance... ;)

Re:Not exactly... (-1, Flamebait)

gatkinso (15975) | more than 5 years ago | (#25195075)

A tenet of TDD is that the basis path coverage if the unit tests is complete.

Who the hell modded your post as "insightful"?

You, and they, are morons.

Re:Not exactly... (1, Funny)

Anonymous Coward | more than 5 years ago | (#25195251)

A tenet of TDD is that the basis path coverage if the unit tests is complete.

Was that intended to be a sentence? In English?

A tenant of programming is to write code that doesn't have any bugs - sometimes it even happens - about as often as the test cases cover all the possible cases.

Re:Not exactly... (1, Informative)

Anonymous Coward | more than 5 years ago | (#25195399)

A tenant is someone who pays rent.

A tenet is a principle or belief on which a piece of doctrine is based.

testing is a waste of time (0, Troll)

larry bagina (561269) | more than 5 years ago | (#25194981)

testing is a waste of time and only means you satisfy the test conditions. You're better off just proving your code correct.

Re:testing is a waste of time (1, Insightful)

Anonymous Coward | more than 5 years ago | (#25195091)

Test driven design works if the tests are complete. Though I will admit I have rarely seen a complete set of tests; and you still need to some old fashion testing (integration testing, real world monkey testing, etc...).

Honestly I think if you're working with "legacy" code, most companies will view the time needed to get add tests as a waste of time.

TDD seems to work better with new projects where you can plan for the testing framework.

Re:testing is a waste of time (0)

Anonymous Coward | more than 5 years ago | (#25195193)

Um, isn't that what testing does (proves your code is correct)?

Re:testing is a waste of time (2, Informative)

Surt (22457) | more than 5 years ago | (#25195487)

No, testing verifies that your code works under certain conditions. A proof that your code is correct demonstrates that your code works under all conditions in a mathematically rigorous way.

Re:testing is a waste of time (2, Funny)

phoenix321 (734987) | more than 5 years ago | (#25196163)

So you solved the Halting Problem, eh?

Re:testing is a waste of time (0)

Anonymous Coward | more than 5 years ago | (#25196405)

Remind me never to hire you.

Re:testing is a waste of time (2, Funny)

HuguesT (84078) | more than 5 years ago | (#25195513)

No. Remember Knuth's aphorism : [stanford.edu]

Beware of bugs in the above code; I have only proved it correct, not tried it.

Re:testing is a waste of time (2, Insightful)

Ragzouken (943900) | more than 5 years ago | (#25195569)

Testing can prove your code incorrect, which you can react to, but it won't prove your code correct.

Re:testing is a waste of time (0)

Anonymous Coward | more than 5 years ago | (#25195603)

Maybe not the crap you write. Tests ensures the correctness of your software. "Correctness" being what you are trying to prove (e.g., requirements testing).

Re:testing is a waste of time (1)

Jellybob (597204) | more than 5 years ago | (#25195335)

I'm currently in process of writing a test harness for some old C code at work, with precisely that aim, so that I can then go on and make changes without worrying that I broke everything else.

Testing doesn't *have* to be on a method by method basis, and sometimes that just doesn't work. In this case it's a program that takes some input, and compares the program's output to what it should be producing.

It's not the most elegant solution ever, and it certainly doesn't test every little corner of the code, but it does prove that the output is correct.

Re:testing is a waste of time (1)

CrazedSanity (872448) | more than 5 years ago | (#25195497)

Building tests for your code proves the code "is correct" (read: "works properly") and bug-free to the extent the testing covers. When new bugs are discovered, tests can be added/modified to check for that, proving your code is still good.

The process of "proving your code is correct," to me, involves lots of face-to-face see-I-told-ya-so's, and displaying how it works. Tests allow you to say with authority, "I wrote 4,322 tests to make sure the system works the way it's supposed to. If you got an error message without the system crashing, you did something wrong."

Re:testing is a waste of time (2, Insightful)

antifoidulus (807088) | more than 5 years ago | (#25195575)

Huh? Despite the fact that proving code correct can be a major burden itself, the long and short of it is that outside of a few niches, most programs have to interface heavily with various hardware vendors, OS's, APIs etc. For example, a lot of our code at work runs on Linux and thus is dependent on Linux behaving a certain way. So go ahead, prove the correctness of Linux first, then maybe we can prove the correctness of our code.

I Got Your Legacy System Right Here (4, Insightful)

cbowland (205263) | more than 5 years ago | (#25194985)

A legacy system is anything that is in production RIGHT NOW. My coding philosophy has always been "building tomorrow's legacy systems today."

Re:I Got Your Legacy System Right Here (1)

Kjella (173770) | more than 5 years ago | (#25195375)

A legacy system is anything that is in production RIGHT NOW.

Wait, so an application goes right from beta to legacy? (Or worse still, it's beta and legacy at the same time?)

Re:I Got Your Legacy System Right Here (1)

cbowland (205263) | more than 5 years ago | (#25195781)

A legacy system is anything that is in production RIGHT NOW.

Wait, so an application goes right from beta to legacy? (Or worse still, it's beta and legacy at the same time?)

Sound like gmail.

Fixed story (0)

Anonymous Coward | more than 5 years ago | (#25194989)

...and the tests will tell automatically you if you broke anything covered by the test cases.

Story submitter missed a few words out.

As someone who hasn't worked with unit tests... (2, Interesting)

Spy der Mann (805235) | more than 5 years ago | (#25195127)

what book can you recommend to me regarding unit tests? After reading the summary, I really got interested in this unit test stuff.

Re:As someone who hasn't worked with unit tests... (1)

tomhermann (977177) | more than 5 years ago | (#25195565)

Start by reading the developer documentation for the unit testing framework you are going to be using (junit for java, cppunit for c++, etc.)

Once you've mastered the basics of getting the framework installed and a basic test passing (e.g. assertTrue(true); ) check out xUnit test patterns [amazon.com] . This book covers a lot of basic unit testing topics along with a number of things not to do while unit testing.

Re:As someone who hasn't worked with unit tests... (0)

Anonymous Coward | more than 5 years ago | (#25195581)

I recommend that you realize if you could write a unit test for every method, which made sure that every function worked properly in every situation, you wouldn't need the original code - you would already have the inputs and outputs.

Avoid the specialist books at first (2, Insightful)

Anonymous Brave Guy (457657) | more than 5 years ago | (#25196565)

While I completely respect your desire to learn, I advise against rushing out to read a whole book on the subject straight away.

The reason I say this is that unit testing is really a very simple idea: you should try to design your code so that you can test each module independently; implement simple, self-contained, automated tests for each part of the interface functionality; and then run your set of tests frequently, ideally between each change you make to the code. This certainly isn't foolproof, because it relies on having a good, comprehensive set of tests and usually it's impossible to cover everything. However, you can still help yourself to find most bugs quickly, and to identify very accurately and immediately where they come from, by using a good test suite. Of course there are some useful ideas and techniques that can help you to do these things more efficiently and reliably, but the basic principle is always the same.

People write whole "frameworks" to deal with this stuff and some books discuss them, but IME these frameworks are in that category of libraries that everyone seems to write but no-one seems to use. It is often simpler and faster to write your own that fits exactly into your particular project than to learn someone else's, create a dependency on external code, and then adapt it to your specific needs anyway.

Likewise, people write whole books on software development approaches like Test Driven Development, which are heavily based on unit tests. However, while there is plentiful objective evidence that quality can be improved by using unit tests, there is precious little beyond anecdotal evidence that anything other than consultants' incomes is improved by adopting TDD and the like. (If anyone disagrees with this, please spare us all the rant unless you can cite verifiable data to support what you're going to say.)

There are some good comments on unit testing in general software development books such as Code Complete, which you might find interesting and useful. But I advise steering clear of the specialist books on frameworks and methodologies built around unit testing, at least until you have enough experience to separate the snake oil from the real oil.

Unit testing in Web programming (1)

Parker Lewis (999165) | more than 5 years ago | (#25195095)

How about unit testing in web systems? I never see other kind of test than test the ActiveRecord classes. Even on JSP/Servlets world is hard to do unit testing in web. Anyone has some tips?

Re:Unit testing in Web programming (2, Insightful)

Surt (22457) | more than 5 years ago | (#25195265)

Try rendering out enough hidden information in your html such that a programmatic test can drive the UI in a meaningful way (ie unique, tree-based ids for every user manipulateable element). Then testing is just a matter of recording the path of interest through the application. A script where I work might look something like:

startpage = login
AdminPage = startpage.clickAdminTab
selectedUserRow = AdminPage.UsersList.SelectRandomUser
selectedUserRow .ClickRevokePrivileges
assertFalse(selectedUserRow.hasPriviliges)

You can imagine how each of those things maps to the relevant html.

Re:Unit testing in Web programming (2, Insightful)

Parker Lewis (999165) | more than 5 years ago | (#25195511)

Thank you for your reply, but you are describing an automated system test, not a unit testing.

Re:Unit testing in Web programming (2, Insightful)

Surt (22457) | more than 5 years ago | (#25195621)

I'm describing a UI level unit test (a test which covers a minimal unit of UI).

If you just want to test your widgets on an individual basis, just use selenium and test pages.

That's the only two facets to web testing I can think of, so if it isn't one of those please explain what you mean. Are you thinking of load testing?

Re:Unit testing in Web programming (1)

mweather (1089505) | more than 5 years ago | (#25195431)

Django has a unit testing system built in. I've never used it, though. My Django apps are always too simple to worry about it.

what can tests really do... (5, Insightful)

drDugan (219551) | more than 5 years ago | (#25195103)

I push back on this mentality each time I see it from the agile crowd: (FTA/review)

"When good unit tests are in place, then code can be changed at will and the tests will tell automatically you if you broke anything."

No. (testing FTW and all, but lets get real)

Tests are *helpful*. Multi-user development beyond 2 people accelerates with good tests. Maintenance long term is easier with tests. Changes happen faster and are more robust with good tests. However, tests are extremely difficult to write well and almost impossible that cover all the possibilities for future changes while also telling future programmers automatically when something doesn't work. I think that the best one could say is this:

When a comprehensive set of great unit tests are in place, then code can be changed at will and the tests will help the programmer understand if they broke anything. Test will often tell you automatically about things that are obvious, and usually would be seen with the most basic release testing. The art of writing good tests is understanding the subtle points of how your code functions and the pitfalls future developers may trip over when they extend what you did.

Re:what can tests really do... (1)

DiegoBravo (324012) | more than 5 years ago | (#25195685)

>>>When a comprehensive set of great unit tests are in place, then code can be changed at will and the tests will help the programmer understand if they broke anything

Sadly, writing tests is boring... and writing the "setup" code of mock objects, dummy/semi-random data, feeding the database with it, etc... is more boring.. but this all is needed for any real-world project. Yet most people assume that trivial junit tests in small non-coupled objects is the rule. Tipically this just avoids weird values in method parameters, but no good full system behavior.

Re:what can tests really do... (2, Insightful)

Precipitous (586992) | more than 5 years ago | (#25195827)

Your argument seems plausible, until you have actually seen the difference in products developed with test-driven / unit test first approaches. The benefits are not what you think they are. I would agree that unit tests are not a panacea, but disagree on

1) The are essential, not just helpful, at least, if you intend to produce software that works.
2) Unit tests do not need to be comprehensive to be useful. They don't need to be great, but great helps.

I tend to agree with you on 1) unit tests are not integration tests, and also do not replace smart human testers. 2) No TDD or agile expert would include the word "anything" in this statement "When good unit tests are in place, then code can be changed at will and the tests will tell automatically you if you broke anything"

Here is what does happen in initial development with TDD / Agile.
First, you write tests first, based on clear user stories. Then you write code to pass to pass tests (one at a time). This saves massive amounts of time: you avoid unnecessary code, over-design, and unnecessary features.

You see a side benefit quickly: In order to get code into true unit tests, each module has to do something meaningful on its own. You avoid the massive stink of excessive interdependency that paralyzes much OO code. (Much of Feather's book is about how to break those dependencies in order to test code).

Now, 1 or 2 weeks later (agile development gives you something interesting to look at in a week or two, not a month or two), it's either time to clean up the code, or you found you really misunderstood the problem. With this test coverage, it is enormously easily to re-factor.

But a warning: If you were writing integration tests (not unit tests), you'll find the tests are in the way. You make 1 change, and 10 tests fail. Done correctly, 1 change, 1 unit test fails. xUnit Test Patterns might be a good book, if you have this problem.

Is the coverage helpful or essential? Most of the code I work on has complexity rated at mind-boggling. Not only is it helpful to have the coverage, it's essential. I don't want to attempt to remember all 200 rules and exceptions when each behavior is complex enough. And don't want to wait 2 weeks for QA to finish their test pass. Good coverage means I make a change, and know immediately. I can let QA know risks that can't be covered in unit tests, and they can do some valuable work in discovery. Essential!

Re:what can tests really do... (2, Insightful)

Drogo007 (923906) | more than 5 years ago | (#25195923)

As a long time Tester (10+ years) and Programmer, I'm going to go one step further:

Writing GOOD tests is HARD.

First you have to think through the use cases, business logic, etc etc etc

Then once you have the tests written, stop and think: Who is going to test that the code you just wrote (unit tests) is actually doing what you think it's doing.

I write test code for a living, and test code still scares the crap out of me for the simple reason that there's no verification happening on the test code itself apart from what the original author of the code does. Simple syntax errors in your tests may mean that what you think is being tested, is actually not being tested at all, or being verified to the wrong spec!

Unit tests are a Very Good Thing (TM)! But they are NOT the end-all-be-all of testing.

Re:what can tests really do... (1)

artg (24127) | more than 5 years ago | (#25196007)

Tests are, indeed, useful. But the idea of using tests as anything other than confirmation of function would be seen as the dark ages in any other branch of engineering. The fact that it's seen as a new concept in software is illuminating ..

In civil engineering, a failed test means major rework. Tests are performed either as research or as a confirmation of safety. In the latter case, they are not expected to fail.

In production engineering, tests were once performed to filter the good builds from the bad. This was far too expensive, and largely explains the success of Japanese industry over British and American in the 70s and 80s. Reworking production because of errors costs a huge amount of effort by skilled personnel : building it correctly takes largely automatic effort by much cheaper employees. Worse still than reworking errors is reworking bad design, where production workers have to tease the required performance out of a marginal design. A small batch of components towards the edge of tolerance can shut down manufacturing.

We like to think that a good software engineer designs and implements correctly and gets it 'right first time' and then the software can be duplicated indefinitely. In exceptional cases, this is true. In many cases, especially where a team is involved or the unit has to work in the context of other software, it isn't : the situation is much more like that of an assembly line. When we truly get to the point where we know how to make it right first time and only fail when we screw up, we'll really be Engineers. Until then, we'll be relying on testing to find basic errors, but it's a cop-out.

What if the legacy code doesn't work? (2, Interesting)

wandazulu (265281) | more than 5 years ago | (#25195165)

I have some legacy code that straight-up doesn't work; it makes references to non-existent proprietary libraries, uses classes that aren't defined anywhere, and just to make things more interesting, a lot of methods with a lot of code, and variables carefully instantiated, that are never used.

This is what is checked into source control; there is a binary that does, in fact, work, based on this code (or some better flavor of).

What to do then? There is some pretty involved financial algorithms in there that were designed by a mathematician and both the original developer and the mathematician have long since left the building. Yet, here I am, with a bug report that one of the models is wrong, and have absolutely no way to fix it.

An earlier comment suggested that the "real" way to was to decry the original author's skills, parentage, etc., and just re-write. Frankly, this seems to be my only option at this point.

Re:What if the legacy code doesn't work? (-1, Troll)

Anonymous Coward | more than 5 years ago | (#25195249)

It sounds like the previous developer was an open source software developer.

Re:What if the legacy code doesn't work? (1)

Surt (22457) | more than 5 years ago | (#25195321)

Carefully instantiated variables that are never used are often changing global state. Having the variable makes debugging easier in some contexts. Not to say this is the explanation for your situation, but it is a reason you'll see that some times.

Re:What if the legacy code doesn't work? (1)

j-pimp (177072) | more than 5 years ago | (#25195349)

I have some legacy code that straight-up doesn't work; it makes references to non-existent proprietary libraries, uses classes that aren't defined anywhere, and just to make things more interesting, a lot of methods with a lot of code, and variables carefully instantiated, that are never used.

This is what is checked into source control; there is a binary that does, in fact, work, based on this code (or some better flavor of).

Look into reverse compiling. Depending on the source language, this might be feasible. If not, disassembling and linking the code in might work in a pinch, but you will need to get the code to compile or rewrite it.

Suing the original developers might be an option. This is flat out negligence. By threating to do so, these developers might be willing "find" the missing source code.

Re:What if the legacy code doesn't work? (0)

Anonymous Coward | more than 5 years ago | (#25195527)

The thing is: does the checked in code compile?
TO the same thing as the binary?
If if doesn't, then make sure your boss knows.

If it does, then there are hacks in the code somewhere to get around these problems. You need to find them.

Re:What if the legacy code doesn't work? (1)

nyabutid (840548) | more than 5 years ago | (#25195665)

Investigate whether there was a compiler dependency in generating the working binary. My experience has been that some setups don't result in a working binary right away. You have to fiddle and almost get t othe point to replicating the initial build environment where the code was run on.

Look at design patterns when reverse engineering the code to somehow have a sandbox where the execution can be monitored.

Test this, test that :) (1)

sw155kn1f3 (600118) | more than 5 years ago | (#25195169)

>> then code can be changed at will and the tests will tell automatically you if you broke anything

*Old legacy dev's pessimistic evil smile*
All right, young man, now please refer me to a book where they have a way to write tests to automatically correct my errors while I drink coffee!
That'd be something. Return when you found one.

Building the Legacy Systems of Tomorrow (3, Insightful)

dwheeler (321049) | more than 5 years ago | (#25195171)

I have this bumpersticker posted on my office wall: "Building the Legacy Systems of Tomorrow [blogs.com] ". I'm not sure who created that phrasing - or the bumper sticker - but I like it.

In short: if it runs, it's a legacy system.

Legacy code (1)

metamatic (202216) | more than 5 years ago | (#25195197)

Feathers' definition is 'code without tests.'

Funny, my definition of legacy code is "code without documentation". If I have documentation for what the code is supposed to do, I can write tests myself. If I don't have documentation, tests won't save me.

Re:Legacy code (0)

Anonymous Coward | more than 5 years ago | (#25195355)

Legacy code is code you're not allowed to redesign / refactor. In most shops, the mainline becomes "legacy code" as soon as you hit the first "freeze" milestone.

Unfortunately the freeze usually happens before the test team has signed off, so you end up with dozens of "highest priority" bugs filed against the dev team. All of these have to be treated as fixes to legacy code, so you're usually not allowed to fix the root cause.

What's that? ... Why yes, I do work at Microsoft. How did you guess?

Except that (1, Insightful)

Anonymous Coward | more than 5 years ago | (#25195479)

Tests ARE documentation.

With the bonus property that the computer can execute them.

Re:Legacy code (2, Insightful)

Surt (22457) | more than 5 years ago | (#25195551)

The really nice to have is where the tests and the documentation are unified, making it impossible for them to diverge. That's what we've built our process around, and it works amazingly well.

encapsulation (4, Informative)

Dan667 (564390) | more than 5 years ago | (#25195279)

The most successful strategy I have had for legacy code that I have inherited is encapsulation of the old code into a new framework. I first attempt to build a black box wrapper with an API for what ever the legacy code did (wrap 5000 line loops, etc). Then as I can or need to change it, I take the black box and break it into proper libraries or readable functions (or start over). Have been able to do this for some really large bases of code and have a working system while I re-factored the mess a little at a time.

Anonymous Coward (0)

Anonymous Coward | more than 5 years ago | (#25195395)

Can you say "Wag the Dog". Anyone can write a test that will pass. Back to Glenford Myers and the "Art of Software Testing".

So when someone asks me... (2, Funny)

ivandavidoff (969036) | more than 5 years ago | (#25195447)

"Say, Ivan -- does your code have tests?" "Nope, it's Legacy Code". "Is it debugged?" "Nope -- legacy." "Does it work?" "Look, I already told you: IT'S LEGACY CODE. GET OFF MY BACK."

About how to move from bad design to good design (1)

Precipitous (586992) | more than 5 years ago | (#25195489)

This book has been essential to me over the last 2 years: I've been keeping the "legacy" parts of a large web application running while others went on to develop cool new features. Let's just say this, there are two different challenges in software:

Challenge 1) Create a good design from scratch. Lots of folks can do this.

Challenge 2) Move from bad design or bad code to good design, while keeping the product running. Transforming a design in small re-factoring steps is vastly harder than rebuilding, but usually necessary.

This book is about that second, harder challenge. It emphasizes testing and testability, because that is how you ensure the product continues to run while you make the necessary changes. It does tend to assume you know what the good design you aim for is.

This is a very important book to have on your bookshelf, and will probably not become obsolete soon.

Excuse me? (0)

Anonymous Coward | more than 5 years ago | (#25195509)

the number of things you can do to introduce unit tests in procedural languages is pretty small

It depends on how well the code is written. Good code is modular, and modules can be tested. If the code is so poorly written that it can't be broken down into testable units, that's the programmers fault not the language. Code like that should just be tossed away. If it can't be tossed away, you'll have to use a bigger definition of "unit", but it still works. I've seen code bad enough that the definition of "unit" was a CLI application in a shell pipeline. By testing the CLI applications we were, in a sense, testing units written in a nasty hodgepodge of shell and Perl scripts.

Now, perhaps the author is referring to the lack of "unit testing frameworks". You don't need unit testing frameworks to write unit tests. I know that might come as a shock to some of the youngsters out there, but you can actually test functions in the same language the code is written in. You can even do things that are more sophisticated than assertions, which some of the unit testing frameworks I've seen seem to think are magic. Then have the test compile and build as part of the standard ``check" target in your makefile.

Re:Excuse me? (0)

Anonymous Coward | more than 5 years ago | (#25195909)

If the code is so poorly written that it can't be broken down into testable units, that's the programmers fault not the language.

Fine, but blame is irrelevant. The original programmer is long gone and we have a job to do.

Code like that should just be tossed away.

Sometimes you can do that, and sometimes it's not expedient. I say, if you understand the code's purpose enough that you can test it, then your "legacy" is trivial. The ability to maintain someone else's inscrutable code, thus generating an even-more-twisted legacy, is the hallmark of the Master Programmer.

Fie! (1)

bperkins (12056) | more than 5 years ago | (#25195589)

When good unit tests are in place, then code can be changed at will and the tests will tell automatically you if you broke anything.

Away vile Panacea!

Keep thy sticky tentacles off management soft and pliable brain!

Ye shall shall not destroy another project schedule with your false promises and soul sucking stupidity!

Begone wretched creature!

Live out your days off of the decaying pulp of so many piles of wasted trees and the scraps tossed to you by management consultants!

Re:Fie! (1)

TheGeneration (228855) | more than 5 years ago | (#25195775)

Seriously. TDD is all management masturbation.

Combinatorial Explosion (3, Insightful)

natoochtoniket (763630) | more than 5 years ago | (#25195729)

Testing cannot detect errors with probability significantly greater than zero, unless the system under test is trivially small. For a system that has N interacting features, the number of test cases that are needed to "cover" all combinations of features is O(2^N). And, that is assuming the simplest possible features that are either used or not used in each case. If any features have complicated (more than one bit) inputs, the base of that exponential complexity function increases.

While tests are helpful to detect implementation errors, test sets cannot be complete for nontrivial systems. And because testing cannot be complete, it can never provide sufficient verification. That is a basic fallacy of test-driven development, and of a-posteriori testing generally.

The least-cost way to prevent bugs that will be noticed by users is to avoid making them in the first place. Requirements and designs can be documented, checked, reviewed, communicated, and (most importantly) read and referenced during subsequent phases and iterations of the development process. Test plans and test scripts can be part of that process, but cannot replace the requirements and design phases.

Cost-driven managers don't like to hear that, though, because they think testing is cheap. Non-automated testing can often be done by cheap and easily-replaced labor. And automated testing is essentially free after the test software itself is developed and verified. (Notice, though, that developing the tests also involves requirements and designs, and increases the total amount of software that must be developed.)

So, the least cost development process involves some reasonable amount of testing, but also involves requirements and designs, and reviews at every step. The only way to defeat the combinatorial explosion is by applying heavy doses of "thinking" and "understanding". Nothing else works as well.

Re:Combinatorial Explosion (2, Insightful)

hondo77 (324058) | more than 5 years ago | (#25195903)

And because testing cannot be complete, it can never provide sufficient verification.

That's like saying that seat belts can't save your life in every car accident so they're not worth wearing at all. Unit testing is but one tool in a developer's toolbox. It is not an all-encompassing solution to all of a project's ills.

Without tests? Try working with legacy code ... (1)

PolygamousRanchKid (1290638) | more than 5 years ago | (#25195747)

... without source!

Believe me, this is not a singularity in the maintenance universe that I am familiar with.

The best is the opening pitch that the customer gives:

"Yes, this is a typical legacy code, blah, blah, blah."

"Um, but we don't have the source."

TDD is a waste of time and money. (3, Interesting)

TheGeneration (228855) | more than 5 years ago | (#25195755)

Not once, EVER have I worked on code where the unit tests broke because of a bug or a mistake. Instead the unit tests break because the new code has something the test didn't anticipate. This is especialy the case in Easy Mock and TestNG.

Maybe if you're working in a system with complex interdependence patterns, but generally it's a waste of time and money and just a management level masturbatory exercise foisted on engineering.
("I'm a super CTO of Cisco System! I'm going to force unit testing across the board, even where it doesn't makes sense! I'm going to be super ISO certified and John Chambers is going to lick my balls after his retirement when I become CEO!")

If you CAN test it.. (0)

Anonymous Coward | more than 5 years ago | (#25195791)

..then it's not really legacy code. It's legacy code when you don't even know the intent of the code, and the behavior of the code itself is the list of requirements.

And then you have to maintain it anyway.

I currently do this, and I usually succeed (though there have been a few incidents), and I'm proud of that. :-)

Yeah, right... (1)

Locke2005 (849178) | more than 5 years ago | (#25195901)

When good unit tests are in place, then code can be changed at will and the tests will tell automatically you if you broke anything.

Unless there is a bug in the unit test code, or some condition the unit test designer didn't anticipate... oh wait, you said "good unit tests" -- have any of these actually been observed in the wild? I have yet to see a unit test simulate what my 7-year old daughter does best -- clicking wildly all over the place until something crashes.

Legacy Code (3, Informative)

Orion Blastar (457579) | more than 5 years ago | (#25195939)

I have had good luck with legacy code, here is what I do:

#1 Figure out what the code does and document it with comments and write a document on it.

#2 Identify variables and objects and what they are used for and any naming convention the code may use.

#3 You need to stick to the original style of writing or rewrite parts of it into your style if it can give a performance boost or make it more stable.

#4 Try to find programming errors and things that do not make sense and rewrite them so that they make sense. Do error trapping and check for nulls and letters entered into number variables and all other sorts of things most legacy programmers overlook.

#5 Work to make the code stable and not crash and run faster before you start adding new features to it. Users don't want to wait 15 minutes to do a report and then have the program crash after their wait.

#6 Work with the help desk to identify the most serious problems that users complain about the legacy code. Make it a "wish list" and then fix each complaint as you have time to do.

#7 Get direction from your managers, tell them what you are trying to do and any problems you have. You need to work as a team with other developers, the help desk, managers, and users to work out the issues with legacy code. Explain to them when you need more time and cannot make the schedule they gave. Make a deal with them to release a stable version but lacking features that might take more time than they thought to do. Tell the users you had to no add in those features to meet a deadline or ask them if they want to wait until you figure out how to add in those features.

#8 Play Sherlock Holmes and read books or Internet web sites on the language and technology used with the legacy code. Search knowledge bases and blogs and forums for answers to solutions, sometimes someone else figured out what you are trying to solve. If not ask on a forum or blog or web site and see who answers. Many of my answers got that way from the Internet on legacy code, but management didn't understand why I spent so much time on the Internet. It was because they wouldn't buy me the books I needed and I had no documentation or anything to work with except for pure code with no comments and all with serious problems. Sometimes I had to spend 5 hours a day researching on the Internet and 3 or 4 hours coding, but in doing so I saved months of work, but management didn't understand that each web site I went to was work related and I looked at the design of sample code even HTML code to get ideas on how to solve the legacy code problems. Sometimes you have to call up a help desk of a vendor to get answers as well, but they docked me for long distance calls to Canada where Crystal Reports and Segate/Business Objects had their headquarters. Fixing Crystal Report errors would make me spend 5 hours a day on the Internet just to figure out what caused double lines in a report and why only certain users got it and not others.

#9 When in doubt ask for help. Sometimes another pair of eyes can spot errors and mistakes that you cannot see. Diversity is a good thing with team members. Form a dream team of programmers of different backgrounds for best results.

#10 When in danger, when in doubt, don't run in circles and scream and shout. Take a walk, get something to drink and relax. Take a mental health break instead of getting angry at other people for not helping you or not doing their jobs properly, they might be suffering from stress like you are and you don't know it. Be positive, not negative.

Re:Legacy Code (1)

serviscope_minor (664417) | more than 5 years ago | (#25196255)

Sometimes you have to call up a help desk of a vendor to get answers as well, but they docked me for long distance calls to Canada where Crystal Reports and Segate/Business Objects had their headquarters.

You continued to work there after they docked you (presumably your pay) for doing your job? If you had any flexibility, you should have quit on the spot and sued them for the money they owed you.

Re:Legacy Code (1)

Orion Blastar (457579) | more than 5 years ago | (#25196395)

Yeah I guess I could have, but it is all in the past. I forgive them for doing that to me, but they did it out of ignorance because they didn't understand what I was doing for them or how valuable it made me.

They suffered for firing me, and could not replace me with someone who could do the job. I am writing these hints and directions and habits to help other programmers be like I once was.

I am getting my marbles back and will become a great programmer again. Maybe they will see I didn't sue them and hire me back as a contractor? :)

I didn't quit because I have a wife and son that need to have a house, if I quit I'd lose my house as I had a lot of medical bills and owed a lot of money to credit card companies to buy the medicine my insurance wouldn't pay for and the books I needed to do my job that my employers would not buy for me.

I had a small business but it only did tech support, as I had a "no compete" contract with them and so I didn't write programs but fixed computers instead to make sure it was a different line of work. But the local tech support businesses ran me out of business, caused my business partner to have a heart attack and I got really sick myself and closed the small business. Then I got fired for being sick on the job, and I was under a lot of stress for reasons I posted above. But I forgive them because they didn't know what they were doing or how valuable I was to them.

I've moved on, and I dug myself into a deep hole I now only recently am starting to get out of.

I've been in hell for like 7 or 8 years or a decade and I just got back to Earth. Now I am back and better than ever. :)

It is easy to test procedural code (1)

lopgok (871111) | more than 5 years ago | (#25196033)

Though it is hard to test spaghetti code, it is hard no matter if the code is procedural or object-oriented. If you have reasonably well written procedural code it is easy to unit test. For C, there is http://cutest.sourceforge.net/ [sourceforge.net] a very simple framework. Lets say you just wrote super_sort. You can write tests to test it with random input, sorted input, reverse sorted input, big input, small input, and the like. If you ever break super_sort, you will find out as soon as you run your unit tests. IMHO, linear algebra may be complex, but there is generally no state. Purely procedural code is fine for it (though C may not be). There are many simple as well as complex things that have no internal state, and will not benefit from object orientation.

Legacy Code (2, Insightful)

devnullkac (223246) | more than 5 years ago | (#25196045)

Feathers' definition is 'code without tests.'

I'll do you one better: Legacy code is anything developed under a different process than you're using now. If all you'll ever do is TDD, then Feathers' definition is fine. But if, like me, you've seen a dozen major development philosophies come and go and be refined over the years, you know that TDD will eventually be supplanted. The only thing that remains constant in the recognition of difficult maintenance is this: "We didn't plan to maintain it the way we're maintaining it now."

Where's the software? (0)

Anonymous Coward | more than 5 years ago | (#25196177)

Feathers defines "Legacy Code" a bit different than you may expect. Feathers' definition is 'code without tests.' Agile programming seems to do this a lot, redefine things till they are happy.

Your code doesn't work? Write Unit Tests. Code still doesn't work? It's because you didn't write "adequate" tests.

In the end you've redefined everything, but you still haven't solved any problems.

When I started out there were two books an structured programming: Constantine and Yourdon, and Page-Jones. There were a few other books on quality programming: Software Tools, Weinberg, etc. later there were other OO books, but still two main books: Booch and Rumbaugh. There were other OO methodology books (Bertrand Meyers, Wirfs-Brock etc ), but they were this diverse group throwing out different ideas.

Now we have tons of Agile books all written by the same clique. But what software have these guys produced? Seems to me that the main purpose of "Agile programming" is to sell books and consultancy classes.

Before you buy Feathers book, I suggest you ask yourself this. Has he been a major contributor to the linux kernel? To Emacs? Eclipse? Mozilla? What software has he written? What do coders whose work we see like Raymond and Stallman think of these guys?

And if Agile is so great, why aren't they writing
some the great software out there?

Definition of 'Legacy' (1)

PPH (736903) | more than 5 years ago | (#25196221)

...is anything you don't like.

I've seen the term thrown around by VB programmers trying to make sense of COBOL or Fortran code. Or IT departments that were going 100% Windows using the term in reference to anything other than a Microsoft product.

To be accurate, it should refer to code (or anything) developed under some other design and maintenance methodology or process than that currently used. That doesn't mean it is bad, old, or untested. In fact, it might be better that the crap you write today.

I used to work for an outfit that did a lot of avionics testing. Back in the old days, the engineering department (the people who build the aircraft systems) designed and built a set of ATE equipment (redundancy noted). One component was a natural language to test code translator. We'd feed in the systems specs written in English (or more often Engrish) and the translator would spit out executable code. The module worked well, was easy to maintain and modify. I was brought in rather late in its life in the company and had no trouble understanding it. But then management mandated all software maintenance to be done by our information systems group (people from the finance department). Since they had no skills in natural language recognition, they just labeled that function 'legacy' and as a result unmaintainable. Their solution was to have the engineering department learn VB and code the ATE tests by hand.

Great book (4, Insightful)

IcyHando'Death (239387) | more than 5 years ago | (#25196303)

I don't know how many of those leaving their pessimistic comments here have actually read this book, but I have. It's actually been on my to-do list to write a book review for Slashdot myself. Long overdue, I thought, given that the book was published in 2005. Now I'm sorry I didn't get around to it, because I think this reviewer, though positive about the book, considerably undersells it.

To those of us stuck doing active development on old, ugly code, every day can feel like we are slogging deeper and deeper into a swamp. Each time we hack in a new change, it makes us feel unclean. We are ashamed of the ugliness of the patch work we are adding to. We know programming used to be fun, but only rarely do we feel the echoes of that now. Mostly we feel dejected. And we've lost our motivation because we are not putting out code we are proud of.

If any of that rings a bell with you then grab Michael Feathers' book the next chance you get. A previous poster said something like "get Martin Fowler's Refactoring book instead", but he's entirely wrong. Not that it isn't a great book, but it won't save you. I've known about refactoring for years without being able to put any of it into practice. The prerequisite to aggressive refactoring is a good set of automated tests, and my projects have not only had no tests, but have seemed down-right untestable.

WELC is your map out of the swamp. And it's a map drawn by someone who has clearly spent a lot of time guiding others out. Feathers knows how tangled your code base is. He knows it doesn't have useful documentation or comments. He knows you are under time pressure but afraid to break funtionality you don't even know about. He has seen it all and he knows how discouraging and hopeless it looks. But he knows the way out, and he'll patiently and calmly
guide you as you break your first dependency, get your first class into a test harness or write your first test case. And before you know it, you are standing on a little patch of solid ground.

Take my advice. Get this book, read it, and put it into practice. It can change your (work) life!

Load More Comments
Slashdot Login

Need an Account?

Forgot your password?

Submission Text Formatting Tips

We support a small subset of HTML, namely these tags:

  • b
  • i
  • p
  • br
  • a
  • ol
  • ul
  • li
  • dl
  • dt
  • dd
  • em
  • strong
  • tt
  • blockquote
  • div
  • quote
  • ecode

"ecode" can be used for code snippets, for example:

<ecode>    while(1) { do_something(); } </ecode>