opencover icon indicating copy to clipboard operation
opencover copied to clipboard

emit TeamCity summary messages

Open Trass3r opened this issue 8 years ago • 6 comments

Would be nice. Maybe only enabled with a --teamcity cmdline option, like in NUnit.

quick hack that works:

 main/OpenCover.Console/Program.cs | 37 +++++++++++++++++++++++++++----------
 1 file changed, 14 insertions(+), 1 deletions(-)

diff --git a/main/OpenCover.Console/Program.cs b/main/OpenCover.Console/Program.cs
index 238b006..f2b19d3 100644
--- a/main/OpenCover.Console/Program.cs
+++ b/main/OpenCover.Console/Program.cs
@@ -435,16 +435,33 @@ namespace OpenCover.Console
                 }
             }
 
-            if (coverageSession.Summary.NumClasses > 0)
+            var summary = coverageSession.Summary;
+            if (summary.NumClasses > 0)
             {
+                logger.InfoFormat("##teamcity[buildStatisticValue key='CodeCoverageAbsCTotal' value='{0}']", summary.NumClasses);
+                logger.InfoFormat("##teamcity[buildStatisticValue key='CodeCoverageAbsCCovered' value='{0}']", summary.VisitedClasses);
+
+                logger.InfoFormat("##teamcity[buildStatisticValue key='CodeCoverageAbsMTotal' value='{0}']", summary.NumMethods);
+                logger.InfoFormat("##teamcity[buildStatisticValue key='CodeCoverageAbsMCovered' value='{0}']", summary.VisitedMethods);
+
+                logger.InfoFormat("##teamcity[buildStatisticValue key='CodeCoverageAbsSTotal' value='{0}']", summary.NumSequencePoints);
+                logger.InfoFormat("##teamcity[buildStatisticValue key='CodeCoverageAbsSCovered' value='{0}']", summary.VisitedSequencePoints);
+
+                logger.InfoFormat("##teamcity[buildStatisticValue key='CodeCoverageAbsBTotal' value='{0}']", summary.NumBranchPoints);
+                logger.InfoFormat("##teamcity[buildStatisticValue key='CodeCoverageAbsBCovered' value='{0}']", summary.VisitedBranchPoints);
+
                logger.InfoFormat("Visited Classes {0} of {1} ({2})", coverageSession.Summary.VisitedClasses,
                                  coverageSession.Summary.NumClasses, Math.Round(coverageSession.Summary.VisitedClasses * 100.0 / coverageSession.Summary.NumClasses, 2));
                logger.InfoFormat("Visited Methods {0} of {1} ({2})", coverageSession.Summary.VisitedMethods,

Trass3r avatar Dec 14 '16 17:12 Trass3r

What information would you want to emit and why is it important to emit them as teamcity messages?

Could you not instead have a tool that parses the XML and emits the messages you require?

sawilde avatar Dec 14 '16 19:12 sawilde

This guy tried parsing the xml but ended up parsing the stdout summary instead.

Unfortunately OpenCover xml reports aren't supported by TC. Only dotCover, NCover etc.

Trass3r avatar Dec 14 '16 22:12 Trass3r

I see - these are the docs for reference purposes - http://confluence.jetbrains.com/display/TCD10/Custom+Chart#CustomChart-DefaultStatisticsValuesProvidedbyTeamCity

sawilde avatar Dec 14 '16 23:12 sawilde

There is also a NuGet package to generate TeamCity service messages: https://www.nuget.org/packages/TeamCity.ServiceMessages/

Sam13 avatar Jan 05 '17 14:01 Sam13

Parsing the XML for the same numbers that are being emitted to stdout is trivial; the more so when you realise that only the 3rd line of the file, the one with the summary record, is of interest, and so you don't need to read in the however many megabytes of report. I have no idea what led the linked blogger to think that the numbers he was getting from stdout were any different from those in the XML <summary> tag, though the talk about line vs statement coverage seems to indicate a degree of confusion about what is being reported.

Making the entirely plausible assumption that this is happening on Windows, the PowerShell needed, which can be added as a build step, is as follows, most of which is writing the data

param([string] $path) # Path to the OpenCover XML log
$x = [xml](Get-Content $path -TotalCount 3 | Select-Object -Last 1)

Write-Host "##teamcity[buildStatisticValue key='CodeCoverageAbsCTotal' value='$x.Summary.numClasses']"
Write-Host "##teamcity[buildStatisticValue key='CodeCoverageAbsCCovered' value='$x.Summary.visitedClasses']"

Write-Host "##teamcity[buildStatisticValue key='CodeCoverageAbsMTotal' value='$x.Summary.numMethods']"
Write-Host"##teamcity[buildStatisticValue key='CodeCoverageAbsMCovered' value='$x.Summary.visitedMethods']"

Write-Host "##teamcity[buildStatisticValue key='CodeCoverageAbsSTotal' value='$x.Summary.numSequencePoints']"
Write-Host "##teamcity[buildStatisticValue key='CodeCoverageAbsSCovered' value='$x.Summary.visitedSequencePoints']"

Write-Host "##teamcity[buildStatisticValue key='CodeCoverageAbsBTotal' value='$x.Summary.numBranchPoints']"
Write-Host "##teamcity[buildStatisticValue key='CodeCoverageAbsBCovered' value='$x.summary.VisitedBranchPoints']"

though in real life, I XSLT the data to NCover format to feed into other report tooling that was developed back in the 1.5x days, and the TeamCity integration just comes for free.

SteveGilham avatar Jun 18 '17 15:06 SteveGilham

I did the experiment based on the above, and I found that

  1. It was better to locate the summary line by wildcard match amongst the first few than by number
  2. If you're embedding the PowerShell in the YAML, then you need to escape in the single quotes
  3. ADDED : "B" for block shows up on the build summary, "R" for branch doesn't

Other than that, It Just Worked.

SteveGilham avatar Jun 30 '17 19:06 SteveGilham