I love Unit Testing

Alright, so I admit that I'm completely biased. I can't be impartial about it and I don't think you should be either. Once you begin writing Unit Tests - or better yet Test Driven Development - you don't want to go back. Once you have a series of Unit Tests for a particular class, method, etc, it's painful and scary to modify code lacking these tests...

But I also see the value in Unit Testing in a few other areas.

A while back, I was the "new guy" on a large Java project that was 4+ years in and had atleast 2+ years to go. There was a huge production codebase written by a series of developers of varying skills, knowledge and experience. I needed to get familiar with specific portions of it and it was my first project as a fulltime consultant. Nerve wracking? Yes. Impossible? No. I dug through the system and found a definite lack of documentation and Unit Testing.

First, like any "new guy" I wasn't expected to be productive for a short period, so I dug in and started writing tests. I implemented complete testing for all the underlying Utility classes and the corresponding methods. By doing this, I was able to completely validate all functionality and even fix a couple of errors. Imagine that, closing bugs in my first two weeks!

Next, I was able to get a better understanding of the supporting fuctionality. This taught me basically nothing about the business logic of the system, but when I began to explore the business logic, I understood the underlying functionality that much better. It also meant that once I needed some of the same functionality, I knew not to rewrite what wa already there, but simply call it.

Next, it gave my customer something to evaluate. During the interview process, many hiring managers believe in having a candidate write code or pseudocode to perform a specific task. Regardless of whether you're doing that, having Unit Tests (aka Actual Code) provides even more information.

Finally, I use Unit Testing as a safety net. The vast majority of Utility classes perform simple data manipulations... parsing strings, calculating dates, or determining results of simple calculations. When I find another Case not originally addressed by the Test, I simply write assertEquals(X, Utils.doSomething(Y)) and watch the output. Since the other tests must pass also, I can know with confidence whether or not I've broken other pieces of code.

If you're not doing any Unit Testing, why not? When you make changes to underlying functionality how do you ensure that all instances will still work?

It's not something that you need to write all in one fell swoop. Implement them in stages. When you expand functionality in a particular class, write a few Unit Tests where they makes sense. Remember, the code should break or not break according to your rules.

Learning Resource

I was wondering if I could get some pointers on learning how to write unit tests. Do you have some good resources, either book or web? I program mainly in VB.Net or C# for web applications. Would unit testing be different for the web than for the desktop?

httpUnit

Although I have never tried it, I've heard that httpUnit works well for web testing. For all the backend stuff, you should be set with nUnit and the .Net Ant equivalent (nAnt?). I always recommend testing as much of your calculation areas, your string parsing, and your Data Access Objects.

This should allow you to confirm the big areas like calculating tax on a shopping cart, properly formatting the date, and loading/saving objects.

Just remember that Unit Testing doesn't need to be done all at once. Write the tests for areas as you have to interact with them. Your system will get progressively better and better as you go.

Conceptual Source: http://groboutils.sourceforge.net/
nAnt: http://nant.sourceforge.net/
nUnit: http://www.nunit.org/
httpUnit: http://httpunit.sourceforge.net/

And just about anything on Refactoring... my favorite is Martin Fowler. He's linked on the blogroll.