Daniel Palme

Daniel Palme

.NET consultant from Germany.

Blog > CruiseControl .NET - Integration of coverage reports

CruiseControl .NET - Integration of coverage reports

Some time ago somebody on Stackoverflow asked how to integrate OpenCover results into CruiseControl .NET. After being asked again, I decided to write a tutorial to show how CC.NET has to be configured.
I created a demo project that uses NUnit, OpenCover and ReportGenerator to generate HTML coverage reports that are integrated into CC.NET.

Prerequisites

The archive CodeCoverage.7z (see 'Downloads') has to be extracted to C:\temp\

Server configuration

The following ccnet.config is used:

<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
  <!-- This is your CruiseControl.NET Server Configuration file. Add your projects below! -->
  <project name="CodeCoverageProject" description="Demo for integration of code coverage results in CC.NET">

    <workingDirectory>C:\Temp\CodeCoverage\</workingDirectory>

    <triggers>
      <!-- check the source control every X time for changes, and run the tasks if changes are found -->
      <intervalTrigger name="continuous" seconds="120" buildCondition="IfModificationExists" initialSeconds="5"/>
    </triggers>

    <sourcecontrol 	type="nullSourceControl" alwaysModified="true"></sourcecontrol> 

    <tasks>
      <exec>
        <executable>C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</executable>
        <buildArgs>CodeCoverage.sln /p:Configuration=Release /t:Build</buildArgs>
      </exec>
      <exec>
        <executable>tools\OpenCover\OpenCover.Console.exe</executable>
        <buildArgs>-register:user -target:tools\NUnit-2.6.1\bin\nunit-console.exe -targetargs:"/noshadow CodeCoverageTest\bin\Release\CodeCoverageTest.dll /xml=reports\TestResult.xml" -filter:+[*]* -output:reports\coverage.xml</buildArgs>
      </exec>
      <exec>
        <executable>tools\ReportGenerator\ReportGenerator.exe</executable>
        <buildArgs>"-reports:reports\coverage.xml" "-targetdir:$[$CCNetArtifactDirectory]\$[$CCNetLabel]\coveragereport"</buildArgs>
      </exec>
      <exec>
        <executable>PowerShell.exe</executable>
        <buildArgs>tools\RemoveScriptsFromReport.ps1 '$[$CCNetArtifactDirectory]\$[$CCNetLabel]\coveragereport\index.htm'</buildArgs>
      </exec>
    </tasks>
   
    <publishers>
      <xmllogger />
      <artifactcleanup cleanUpMethod="KeepLastXBuilds" cleanUpValue="50" />
    </publishers>

  </project>

</cruisecontrol>

This configuration does the following:

The build script is pretty straight forward, the only thing that is important, is the target directory of ReportGenerator. The HTML report has to be placed in $[$CCNetArtifactDirectory]\$[$CCNetLabel]\coveragereport, otherwise CC NET will not be able to display it.

After configuring the server, you can now integrate the HTML coverage report into the Dashboard. Therefore we have to add the following line to dashboard.config (in the <buildPlugins> section):

<htmlReportPlugin description="Coverage Report" actionName="coverageReport" htmlFileName="coveragereport\index.htm" />

After restarting IIS, you can view the build results. The menu on the left side will contain a new item 'Coverage Report'. When you click on it, you will see the following view

CCNET - Code Coverage

Updates

31.05.2013: Updated to latest version of ReportGenerator.

Downloads

CodeCoverage.7z


Subscribe to RSS Feed

 

Related posts

 

New comment

:

:

:

:

 

Comments

#1
Anand

Anand

04/10/2013

Hi Please can u please let me know where is CCNetArtifactDirectory ?
I see only 3 folders inside CCNET install folder:

C:\Program Files\CruiseControl.NET\server
C:\Program Files\CruiseControl.NET\webdashboard
C:\Program Files\CruiseControl.NET\Examples
 
#2
Daniel

Daniel

04/10/2013

@Anand:
I'm sorry, I don't have CruiseControl installed right now.
But it should not be too hard to find, if you take a look at the log files of your build.
 
#3
Anand

Anand

04/10/2013

Hi Daniel,

I found the solution. It is defined in CCNET.config file.
<project name="Test Build">
<webURL>/</webURL>
<workingDirectory></workingDirectory>
<artifactDirectory></artifactDirectory>
<modificationDelaySeconds>600</modificationDelaySeconds>


 
#4
ANAND

ANAND

04/10/2013

One more question
where do i need to keep ReportGenerator.exe. below line doesnot display the absolute path:
<executable>tools\ReportGenerator\ReportGenerator.exe</executable>
 
#5
Daniel

Daniel

04/10/2013

@Anand:
You have to extract the whole 'CodeCoverage.7z' to 'C:\temp'.
Therefore ReportGenerator.exe is located at 'C:\temp\CodeCoverage\tools\ReportGenerator\ReportGenerator.exe
 
#6
Ryan

Ryan

06/04/2013

Thanks for this walkthrough, it really helped. But how did you handle the relative links in the report being displaying in CCNET? The index.htm page displays correctly, but if you attempt to drill down into the report, it breaks since CCNET can't find the sub-report (at least this is the experience I'm getting).
 
#7
Daniel

Daniel

06/04/2013

@Ryan:
CCNET handles the links internally. But this only works for static links. I f links are generated in JavaScript it won't work. Last week I added a script "RemoveScriptsFromReport.ps1" which fixes the problem by commenting out the JavaScript in the report.
If you run this script after generating the report, even the sub-reports should work then.
 
#8
Ryan

Ryan

07/02/2013

Ok, I see what you're doing with script. It inspired me to fix it so that it would work with CCNET. Here's what I did in place of your PowerShell exec (slightly modified to match the paths in your example):

<exec>
<description>Update report paths for CCNET</description>
<executable>PowerShell.exe</executable>
<buildArgs>-ExecutionPolicy RemoteSigned -NonInteractive -Command "&amp; { (Get-Content $[$CCNetArtifactDirectory]\$[$CCNetLabel]\coveragereport\index.htm).Replace(', \"reportPath\" : ''', ', \"reportPath\" : ''RetrieveBuildFile.aspx?file=CoverageReport\\') | Set-Content $[$CCNetArtifactDirectory]\$[$CCNetLabel]\coveragereport\ccnet-index.htm }"</buildArgs>
</exec>

I output the new file as ccnet-index.htm so that I could keep the original reports untouched. Then I updated the <htmlReportPlugin /> to use ccnet-index.htm.