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:
- 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.
- 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.
- 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.