I'm not sure about anyone else but when I come across something that is boring and repetitive I usually get around to doing some tool that minimizes the amount of time I spend doing it. In this case the task that is boring me is writing the repetitive C# code to call BizUnit to make it run your tests. I'm sure there are lots of different ways you could do this but one day when I was stuck waiting for a while at the airport I got bored and decided to do something to stop me having to do this.
The aim of the tool was as follows:
- Don't write anymore C# code to call BizUnit tests, I want to generate it
- Maintain a simple list of tests which can be easily updated
- Include the tool in the build process so that any newly added tests have the appropriate C# code created
I made the following decisions about the tool I would create:
- I decided to make an MsBuild task so it would easily plug into the build process and also regenerate the C# each time
- I decided to use an xml list of the tests. I could have looked for files which were BizUnit tests but this would probably need to have some kind of file naming convention.
- I wanted to wrap the call to BizUnit with a try/catch block so I could log the error to the event log. This is particularly useful when you run the tests from the command line and you don't see all of the failure details.
- The task would be easily configurable so it could use Nunit or MsTest to run the tests.
Using the Task
Before I get into how I built the task I think if I explain how it is used it should seem simple and easily usable. We have used this task on a couple of projects and it has been quite handy.
To begin with we have the below image from the sample project. In this picture you can see the following things:
- A folder containing 3 BizUnit definition files
- The BizUnitTestDefinitions.xml file which describes the tests within the project and determines the code that will be generated.
- The OverrideBuild.targets file which is imported by the project file and contains overrides for some of the build events (more on this later)
- The BizUnitTests.cs file which is the code file which gets generated
As I mentioned this file is the one that describes the tests within the project. The below picture shows an example of this xml.
The key points of the xml are as follows:
- The TestGroup element allows you to group related tests. Each TestGroup will produce a class containing tests. The Name attribute will become the name of the test class.
- Each Test element will become a method which will run a test. It will be contained within the class from its associated TestGroup. The Name attribute will become the name of the test
- The BizUnitTestCasePath element will point to the file containing the details of the BizUnit test. In this case because the example project uses MsTest I have copied the BizUnit tests to the test results directory using the TestRunConfig so I dont need to worry about the path.
This file is imported by the project file allowing me to specify MsBuild targets to customise the projects build process. The contents of this file are below:
In this file I have a target which overrides the BeforeBuild target. This is because I want to generate the class containing my tests before the project is compiled. The key points of this file are:
- The UsingTask element imports my custom MsBuild task so I can use it
- The use of my task in this case is set to use MsTest, but you could easily use Nunit instead by specifying the appropriate values for the TestAssemblyName, TestFixtureAttributeName and TestMethodAttributeName.
This task will basically take these parameters and inspect the xml definition of the tests then produce the output file containing the C# code.
This file contains the code which is generated. An example of some generated code is in the picture below:
The couple of key points to note are:
If there is any interesting feedback on this post I will probably do a follow up describing how the MsBuild task is build. In the meantime the code for the task, and also the sample project are available at the below location so you should be able to see this for yourself.