Search code examples
f#teamcityf#-fakedotcover

FAKE (F# Make) dotCover coverage in TeamCity


I have a FAKE build script that contains a DotCover coverage step using using the DotCoverNUnit3 extension:

let filters = ""

!! (buildDir @@ "/*.UnitTests.dll")
    |> DotCoverNUnit3 (fun p -> 
        { p with
            Output = artifactsDir @@ "NUnitDotCover.snapshot"
            Filters = filters }) nunitOptions

The snapshot generates correctly, but the coverage overview doesn't appear in the TeamCity build.

I then tried calling DotCoverReport after building the snapshot:

DotCoverReport (fun p -> 
    { p with 
        Source = artifactsDir @@ "NUnitDotCover.snapshot"
        Output = artifactsDir @@ "NUnitDotCover.xml"
        ReportType = DotCoverReportType.Xml }) true

This generates the expected XML report, but again, the coverage overview doesn't appear in the build overview page.

As a side note - I'm not sure what the boolean parameter on the end of the DotCoverReport method is, can't find a reference to it on the FAKE docs. I tried switching the value, but it didn't make a difference.

Does anyone know how I can get TeamCity to pickup the DotCover report?


Solution

  • Found a solution.

    After drilling down through many layers of TeamCity documentation, I found this page: https://confluence.jetbrains.com/display/TCD9/Manually+Configuring+Reporting+Coverage

    Which describes using service messages to point TeamCity in the direction of the snapshot.

    So, in the end I didn't need the DotCoverReport, just the snapshot:

    For dotCover you should send paths to the snapshot file that is generated by the dotCover.exe cover command.

    This is my resulting Target:

    let artifactsDir = environVarOrDefault "ARTIFACT_DIR" (currentDirectory @@ "artifacts")
    
    let nunitOptions nUnit3Defaults =
    { NUnit3Defaults with
        TimeOut = TimeSpan.MaxValue
        WorkingDir  = artifactsDir }
    
    Target "TestCoverage" (fun _ ->
        let filters = ""
    
        !! (buildDir @@ "/*.UnitTests.dll")
            |> DotCoverNUnit3 (fun p -> 
                { p with
                    Output = artifactsDir @@ "NUnitDotCover.snapshot"
                    Filters = filters }) nunitOptions
    
        tracefn "##teamcity[importData type='dotNetCoverage' tool='dotcover' path='%s']" (artifactsDir @@ "NUnitDotCover.snapshot") 
    )