4

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?

Dan Ellis
  • 5,537
  • 8
  • 47
  • 73
  • 1
    From here https://github.com/fsharp/FAKE/blob/master/src/app/FakeLib/DotCover.fs, I can see that the bool is whether to fail the overall build if the task fails. The parameter has no name because `DotCoverReport` returns a curried function. It should probably explicitly receive and pass on a named parameter instead for documentation. – TheQuickBrownFox Jul 13 '16 at 09:56
  • Ah I see, I think, so the bool is the `failBuild` parameter of `buildParamsAndExecute` – Dan Ellis Jul 13 '16 at 10:06

1 Answers1

2

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") 
)
Dan Ellis
  • 5,537
  • 8
  • 47
  • 73
  • Hi , I tried using this but it is giving an error that is ` nunitOptions is not defined` –  Mar 24 '17 at 07:44
  • 1
    @johnfernandes I think dan-ellis must have declared nunitOptions in an outer scope. If you have no options to set you could just replace `nunitOptions` with `id` – Joachim Chapman Mar 28 '17 at 10:12
  • 1
    @joachim-chapman correct, @johnfernandes I've updated my answer with the code that defines `nunitOptions` – Dan Ellis Mar 29 '17 at 12:10
  • what is path='%s' here ? – KMittal Apr 05 '17 at 10:56
  • 1
    @KMittal `path='%s'` is part of the format string provided to `tracefn`, the `%s` is replaced by the snapshot file path which is the second argument of the `tracefn` function call. Think of it like a string replace, where we're replacing `%s` with the path of the snapshot file, `tracefn` does the string replacement and then writes the resulting string to the command line. – Dan Ellis Apr 06 '17 at 16:22