Update: This task has been updated, I strongly recommend you download that drop instead of this one. You can read all about it.

Yesterday I got an e-mail from Steve Smith of ASPalliance fame (among other things). Steve wanted to know whether I had ever seen a NAnt task for a unit testing tool called csUnit. I knew csUnit existed by being a long time devotee of NUnit (another unit testing framework) I'd never found the need to go hunting for a task to plug it into my build scripts.

I asked Steve what his reasons for prefering csUnit over NUnit were. He listed a few features, but the one that really stuck out in my mind was the [FixtureSetUp] and [FixtureTearDown] attributes which you can apply to methods in your test fixtures so that they get executed when the fixture is created and discarded respectively. This is a feature that I have long felt that NUnit needed, and something I could have used in my test code more than once.

As a direct result of this I spent last night writing version one of a task which allows me to easily integrate tests designed to work with that unit testing tool into my NAnt build scripts. You can grab a copy of the source and try it for yourself. Please keep in mind that this is just an initial drop, and its missing a number of very important features. I have the following features on my TODO list.

  • Write automated unit tests using csUnit (chicken and egg scenario).
  • Write automated build script to run unit tests and build a release.
  • Improve (have some) API documentation for the source code using XML comments.
  • Make the NAnt output look prettier (looks like a dogs breakfast at the moment).

Hooking up the task is as simple as dropping the NotGartner.Build.Tasks.dll assembly file into the same directory as the NAnt executable. If you can't do that you can load it in from a location you specify inside the build script using the task. The task itself is very simple to use, "just" provide an assembly attribute pointing towards the assembly containing the unit tests and you are away.

If you have more than one assembly that you want to run against you can use an fileset with includes and excludes. When using the fileset the assembly attribute cannot be used, thats just an arbitary limitation I put in to avoid any confusion (good or bad?).

Established users of csUnit might have a set of "recipe" files. Instead of referencing the assemblies directly you can specifiy that the task use the recipe file instead. Like the assembly attribute and assemblies attribute, this option is exclusive.

Under the covers, using the assembly attribute or the assemblies fileset results in a temporary recipe file being generated. The recipe file is then passed to the csUnitCmd.exe executable to have the tests run. This means that this task does not compile against the csUnit libraries at all which should allow more flexibility in the future as framework versions get out of sync.

The task tries to guess the location of the csUnitCmd.exe executable by finding out there the official "Program Files" directory is and then going to "csunit.org\csUnit 1.9.4\csUnitCmd.exe" from there. If you haven't installed csUnit or have installed it into another location then you can override this behaviour by specifying a program attribute on the task.

This is great if you want to lock in the version of unit testing tool you are using along with the source. I do a smilar things with NAnt and NUnit already. Speaking of versions, I have only manually tested this with version 1.9.4 of csUnit, I believe the earlier version 1.9.2 had a problem with the XML reporting function that this task relies on (can anyone confirm or deny this?).

By default csUnitCmd.exe spits out an XML file next to the unit test assemblies containing the test results. The task forces the output to a temporary file which it removes (along with the temporary recipe file if it needed to be created) after the results have been retrieved. If you need to keep the test results then you can override this behaviour by providing an output attribute on the task.

When this attribute is specified the file is not deleted when the task finishes. Well, thats just about it, I hope you csUnit fans out there find this useful. If you encounter any problems   and let me know, I'll add any bugs encountered to my TODO list and try and ship an updated version at some point in the future.