Is it a Good Idea to Write Tests for Legacy Code?

A colleague of mine sent me an article on ArsTechnica that was a short discussion on whether it is a good idea to write tests for legacy code. This was made up from a collection of posts on Stack Exchange. The original question was as follows:

Suppose one had a relatively large program (say 900k SLOC in C#), all commented/documented thoroughly, well organized and working well. The entire code base was written by a single senior developer who no longer with the company. All the code is testable as is and IoC is used throughout—except for some strange reason they did not write any unit tests. Now, your company wants to branch the code and wants unit tests added to detect when changes break the core functionality.

Is adding tests a good idea? If so, how would one even start on something like this?

Original question posted by Paul over at Stack Exchange

It’s a good question, so I thought I would write down my thoughts on it. I am a firm believer in Test Driven Development (TDD) and this is much easier when you are working on a nice new green field project (writing a new system). Unfortunately we don’t always have the luxury of working on new systems and we have to maintain older legacy systems, or brown field applications. If you have a large brown field system, I personally do not think there is much value in getting your team of developers to sit there and wrap the whole system in tests. Whilst it may feel nice to know the application is covered in tests, the level of effort and expense in doing so is likely to be very high indeed. If the system has been around for a long time, then it is most probably working fine and your users are happy with it (this isn’t always the case, but is more often the case).

Legacy Systems
Legacy Systems

What I do feel is valuable though is adding some tests when you need to change/extend part of the code base. As the system already exists and you can’t reliable determine that the code is doing what it should be doing you can write what Michael Feathers describes in his book “Working Effectively with Legacy Code” calls characterization tests. A characterization test is:

Continuous Testing with NCrunch

Disclaimer: I currently do not own or have been given a license to NCrunch. I am forming my opinions of it based on the use of the 30 day evaluation license.

In this article I want to talk about a very useful tool called NCrunch. I have had a few people recommend the tool to me recently, so I thought I would check it out. I am glad I did. So, what is NCrunch? The description on their site explains this nicely.

Continuous Testing with NCrunch
Continuous Testing with NCrunch

NCrunch is an automated concurrent testing tool for Visual Studio .NET. It intelligently runs automated tests so that you don’t have to, and gives you a huge amount of useful information about your tested code, such as code coverage and performance metrics, inline in your IDE while you type.

On reading that I first though, hmm, well doesn’t visual studios test explorer do that, and it does, but this tools goes a step further. In essence NCrunch executes tests in the background whilst you work giving you continuous feedback. Initially I thought that’s not really such a big deal. One of the projects I am working in has 690 unit tests and because they are true unit tests, as in they don’t hit databases or external resources, then they only take 20 seconds or so to run. Even though this is the case you still get into the compile, run the tests, check the results, fix or carry on loop.

All Your Mocks are Evil!!

In unit testing, all mocks are evil! Now there’s a controversial statement to start a blog post with, but let me explain. I am writing this from my own experience as a software developer and a leader of software developers. This is the sort of thing that software religious wars are made of, so if you agree, or disagree, I would love for you to share your thoughts in the comments.


I think Mocking libraries, although very powerful, can enable developers to over complicate their unit tests. Unit tests should be short and easy to understand. I have lost count of the times where I have seen a developer mock out more than they need to because of excessive class coupling in their code. Just because you can mock out any object doesn’t mean that you should and avoid reducing excessive coupling.

%d bloggers like this: