One of my goals is to become more skilled with CruiseControl.NET because Continuous Integration plays a big part in Agile Development. Today I took the first step. It wasn't one of those easy, comfortable steps. That's why I'm documenting my results.
Here are some of the steps I took today to get a CruiseControl server running on my computer with integrated NUnit Reports. Some of these steps could definitely be improved upon. I don't like using absolute paths if I don't have to but I broke that rule left and right. This is just the first time I've gotten all this working (and trust me, it took hours).
Install Cruise Control
I installed version 1.5.6804.1 of CruiseControl.NET and after realizing that by default Vista does not enable ASP.NET, it ran quite nicely.
Incorporte NUnit into the Build Process
I wanted to make NUnit run as part of the Visual Studio 2008 build process. I tried to use the Microsft SDC NUnit Task but after hours of tracking down unhandled exceptions in the NUnit task, I decided to switch to Tigris' MSBuild NUnit Task which worked great the first time.
I had to import the tasks in my Unit Test assembly's csproj file:
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
And then I added the following to the same csproj file:
<IemGroup>
<TestAssemblies Include="$(TargetPath)"/>
</ItemGroup>
<Target Name="Test">
<NUnit
Assemblies="@(TestAssemblies)"
ToolPath="C:\Program Files (x86)\NUnit 2.5.3\bin\net-2.0" />
</Target>
The last step was to add "Test" to the Project element's DefaultTargets attribute:
<Project ToolsVersion="3.5" DefaultTargets="Build;Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Now, whenever I built the project, the tests would run. If the tests failed, the build would fail too. I had to change the MSBuild verbosity to normal to see the actual results of the unit tests. This has the side-effect of showing too much information. If I figure out how to get the NUnit test results showing without showing too much information, I'll write another blog entry.
Build the Project with CruiseControl
I added the following to my ccnet.config file:
<project name="MyProduct">
<category>Production Code</category>
<tasks>
<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>
<workingDirectory>C:\Users\Tim\Projects\CruiseControl\CruiseControlTests</workingDirectory>
<projectFile>CruiseControlTests.csproj</projectFile>
<buildArgs>/noconsolelogger /p:Configuration=Debug /p:Platform=AnyCPU /v:diag</buildArgs>
<targets>Build;Test</targets>
<timeout>900</timeout>
<logger>C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>
</tasks>
<publishers>
<merge>
<files>
<file>C:\Users\Tim\Projects\CruiseControl\CruiseControlTests\TestResult.xml</file>
</files>
</merge>
<xmllogger/>
</publishers>
</project>
The merge elements are required so that the output of the unit test run could be reported on.
Getting Reporting To Work
In the dashboard.config file I had to make a few changes too. To make a change take effect, I'd recycle the CruiseControl app pool.
I added the following elements (shown in context):
<buildPlugins>
<buildReportBuildPlugin>
<xslFileNames>
<xslFile>xsl\unittests.xsl</xslFile>
and then I added this right after </buildReportBuildPlugin>:
<xslReportBuildPlugin description="NUnit Details" actionName="NUnitDetailsBuildReport" xslFileName="xsl\tests.xsl" />
<xslReportBuildPlugin description="NUnit Timings" actionName="NUnitTimingsBuildReport" xslFileName="xsl\timing.xsl" />
After recycling the app pool, everything worked great.