:-$

Ryan's work blog

My Links

News

The WeatherPixie
Subscribe with Bloglines
About this blog

Tools I use:

Post Categories

Article Categories

Archives

Image Galleries

Blog Stats

Personal

Projects

Random Blogs

Random other

Reference

Web comics

Work

NAnt, NUnit, NDoc, Oh my!

So, my confidence in open source was riding high after my experience with log4net, so I decided to try some more.

Summary of tools
If I can find the time, I'll put together more in-depth articles for these, but for now, just an overview:
  1. NDoc is a tool for generating HTML or CHM documentation based on the XML comments in your code. It's very similar to Javadocs, and can even generate HTML in that style. I've been using this one in a few places for a little while. Their GUI is very easy to use, and their command-line utility has good documentation.
  2. NUnit is a unit testing framework written in C#. The idea is you write a lot of small, atomic tests, and then at any point in development you can make a huge change and run your tests to find out where you screwed up. NUnit has the concept of TestFixtures, which is an attribute you add to any class you want to run test in. You slap that attribute at the top, then make your tests, giving them the Test attribute, and away you go, it uses reflection to figure out the rest.
  3. NAnt is a build system that is a replacement for makefiles. It lets you specify targets and such like makefiles. This is by far the most complicated of the three, but it still only took a half day to get it to do what I wanted.
How I'm using them
We're working on a large internal project, so I'm using it as an excuse to spend time getting a decent build system going. So far building has been via Visual Studio (not bad) and testing has been manual through the browser (probably bad). The project is divided into several different assemblies, with one of them being for testing.

NUnit
After futzing around getting my bearings for a few days, I established my unit test pattern:
Make a parallel namespaces in the Tests project, and put tests for actual class X in test class XTest, and have XTest inherit from X. Each XTest is marked as a TestFixture. Initially I had a problem with connectionstrings, but that went away when I ran tests through NAnt. It enabled me to specify a .config file to use with the test. I'm guessing there's a way to do that with the NUnit GUI, but once I got NAnt going, it wasn't an issue.

I had a big problem with side-effects of my tests. I'm testing database code, so that naturally affects the database. I've read a little about Mock Objects, but part of what I want to test is the stored procedures called from my generated objects. I tried to make all my tests clean up after themselves in object-space, but that proved extremely ugly, forcing me to add superfluous member variables and output parameters so I could get a reference to everything I had added. It turned the API really nasty.
I then discovered the TestFixtureSetUp and TestFixtureTearDown attributes, which allowed me to specify code to be run at the beginning and end of a TestFixture. At that point I had only one TestFixture, so it was perfect. I got it backing up the DB everytime, learning more about the T-SQL RESTORE command than I felt was appropriate. When I started adding more test fixtures, it became a problem. There doesn't seem to be a place to specify a global SetUp or TearDown. NUnit does have the idea of test Suites, where you explictly instantiate every TestFixture and run each test, but their page on it seems discouraging of that, and I don't want to do even more extra work. This is where I decided to employ NAnt.

NAnt
NAnt's system of build targets let me specify things nicely. I set up a NAnt task to build the project, another to run the tests, and then started in on working the database into it. After much discussion with other programmers, who for the most part, didn't care either way, I decided on a solution suggested by my friend Chris Black. He suggested to make a copy of the real DB, and run the tests on that. If the tests screw up, it doesn't matter. I liked that over making a backup beforehand and restoring afterwards, which might cause some concurrency issues. So I wrote a program to restore the DB as DB_UnitTests, and set up the NAnt tasks to do so before running the tests. Eventually I made it better, adding another task to get a new backup of the real DB.

I end up with a command prompt up on monitor number two, constantly running things like nant test, nant clean-test, and nant doc.

NDoc
I expected this to be the smoothest part to get working, but it actually took some effort. NAnt has a built-in task to run NDoc, allowing you to specify the assemblies to document there in your NAnt build file, but I couldn't get the damn thing to work. It would generate 4500 HTML files, but there'd be no index.html, and Windows Explorer really does not like to have that many files in a folder. I wound up configuring a NDoc project using the NDoc GUI, and then calling the command-line version of NDoc from NAnt. It takes about 10 minutes to generate the documentation, so its certainly not something done on every build. And thats 10 minutes of 100% CPU usage. I'm guessing this is the type of thing I'd do when I'm on my way out the door. I also added something in there to make a windows help file (CHM), and have that being copied into a different folder using NAnt, so I can open that without needing to choke my computer with a few thousand files in a folder.

Check out these tools, I think they are going to be a good long-term time investment.

posted on Tuesday, December 07, 2004 8:42 PM