Recently, I setup a local CruiseControl.NET Server for a project I’m working on. In order for CCNet to execute a MSBuild project, you need to configure CCNet.config, this is found in your installation directory for the server – in my case ‘C:Program FilesCruiseControl.NETserver’.
The basic structure for a ccnet project would look something like this. You have a project and within that you have a series of tasks (you can find a more complete sample on the documentation page – http://ccnet.sourceforge.net/CCNET/Configuring%20the%20Server.html). These tasks are CCNet tasks, built into the server to use as part of your build process. In my example, I’m using the MSBuild task to build MyProject.sln.
At this point, my project happily building, next I want to execute my NUnit tests and have my results displayed in the web dashboard.
After my first attempt of using the CCNet NUnit task, the unit tests failed because I was referencing a file (naughty I know) on the disk and as NUnit shadow copies all of it’s assemblies so they aren’t locked I realised I needed to disable Shadow Copy. A very simple task I thought, NUnit accepts a parameter on the console application for this.
A quick look at the NUnit CCNet Task page and I was faced with a bit of a problem. The NUnit task looks like this:
Notice, no element for setting the command line properties!!! Such a core feature I can’t believe it was missed. After a quick chat with the build manager at Red Gate, he pointed me towards http://msbuildtasks.tigris.org/ and their NUnit Task. This is a set of MSBuild Community Tasks which you can use as part of your msbuild script to perform various tasks – such as executing nunit tests.
Creating a MSBuild Script using MSBuild community tasks
MSBuild is a build system which defines how to build your .Net solutions. The script is based on xml, the basic outline is below:
As part of this I am importing the MSBuild community tasks targets file, this will allow me to use the tasks later on. Notice at the top within the project element, I have defined a DefaultTarget (DefaultTargets=”Test”). As far as I can tell, this is the target which will be executed first when the script is built, this will make more sense in a moment.
Once we have this in place, we need to define some tasks. In the example below, the first target is the build. This target has a single task, run the MSBuild task against my solution with the configuration as release. This will execute MSBuild to compile my application – excellent!
After the build target, we have the ‘Test’ target, as defined in the DefaultTargets this is what is executed first. I then use the DependsOnTarget to define the task which should be run before the current task, the ‘Build’ target could also depend on other targets. As a result, everything gets built in order based on their dependencies. This Test Target executed NUnit and runs the unit tests for MyProject.Tests.dll and outputs the results to nunit-results.xml. The continue on error property defines if the build should fail if a test fails – which it should!
ToolPath=”E:CCNetToolsNUnit”
DisableShadowCopy=”true”
OutputXmlFile=”$(Logs)nunit-results.xml” />
The most important line for me was the ability to DisableShadowCopy as a property, the reason why I had to use the community tasks.
By using this, I can now have CCNet run this MSBuild script which in turn builds and executes my unit tests. Hopefully, this gives you a very quick overview of how to use the MSBuild community tasks. In a later post, I will explain my complete MSBuild script for my current project and how I utilise the community tasks.
Note:
There are more advanced ways of managing your ccnet config and your MSBuild scripts, if you are managing a number of different projects I would really recommend you investigate different ways of managing the config. This post was just how to manage your first project.
Ben,
I just ran into this issue and after a couple of hours of banging my head against the wall, I downloaded the CC.NET source code and modified the NUnitArgument.cs file to include the /noshadow parameter. Works like a charm!
If you’re interested, here are the steps:
1. Download the source from: http://ccnetlive.thoughtworks.com/CCNet-builds/1.4/1.4.0.3507/CruiseControl.NET-1.4.0.3507.source.zip
2. Download the modified NUnit args file from:
http://www.kitsirota.com/media/code/cc.net/
3. Unzip CruiseControl.NET-1.4.0.3507.source.zip
4. Copy NUnitArguments.cs to {cc.net_source_root}projectcoretasksNUnitArguments.cs
5. Run {cc.net_source_root}b.bat
6. Navigate to {cc.net_source_root}projectsserver and run ccnet.exe
No additional packages, no overhead, Enjoy!