I have a .Net 5 solution with multiple projects and multiple test projects. I want to make sure either everything or a specified percentage value (e.g. 80%) got covered by tests. I'm using xUnit for my tests and created the following Powershell script based on the docs
dotnet test --collect:"XPlat Code Coverage";
reportgenerator -reports:'**/coverage.cobertura.xml' -targetdir:'CoverageReports' -reporttypes:'Cobertura';
[XML]$report = Get-Content CoverageReports/Cobertura.xml
if($report.coverage.'line-rate' -ge 20)
{
Write-Host "greater or equal than 20"
}
else
{
Write-Host "less than 20"
}
Read-Host -Prompt 'done'
which does the following
- it runs the tests and creates one cobertura file per test project
- it merges every cobertura file into one and puts it into the CoverageReports directory
- it parses the .xml file
now I have access to the coverage info, e.g. the line-rate. Instead of the dummy if statement, how can I achieve the following sample?
if($report.coverage.percentage -lt 80)
{
Write-Host "Coverage is less than 80 percent"
}
and as a bonus I could write down a list of things that are not covered yet.
This is the content of a generated Cobertura.xml file from a dummy project
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">
<coverage line-rate="1" branch-rate="1" lines-covered="4" lines-valid="4" branches-covered="0" branches-valid="0" complexity="4" version="0" timestamp="1627911309">
<sources>
<source>C:\</source>
</sources>
<packages>
<package name="ClassLibrary1" line-rate="1" branch-rate="1" complexity="3">
<classes>
<class name="ClassLibrary1.BoolReturner" filename="C:\...\ClassLibrary1\BoolReturner.cs" line-rate="1" branch-rate="1" complexity="3">
<methods>
<method name="Get" signature="(...)" line-rate="1" branch-rate="1" complexity="1">
<lines>
<line number="5" hits="3" branch="false" />
</lines>
</method>
<method name="GetFalse" signature="()" line-rate="1" branch-rate="1" complexity="1">
<lines>
<line number="6" hits="1" branch="false" />
</lines>
</method>
<method name="X" signature="()" line-rate="1" branch-rate="1" complexity="1">
<lines>
<line number="7" hits="1" branch="false" />
</lines>
</method>
</methods>
<lines>
<line number="5" hits="3" branch="false" />
<line number="6" hits="1" branch="false" />
<line number="7" hits="1" branch="false" />
</lines>
</class>
</classes>
</package>
<package name="ClassLibrary2" line-rate="1" branch-rate="1" complexity="1">
<classes>
<class name="ClassLibrary2.StringCombiner" filename="C:\...\StringCombiner.cs" line-rate="1" branch-rate="1" complexity="1">
<methods>
<method name="Combine" signature="(...)" line-rate="1" branch-rate="1" complexity="1">
<lines>
<line number="7" hits="2" branch="false" />
</lines>
</method>
</methods>
<lines>
<line number="7" hits="2" branch="false" />
</lines>
</class>
</classes>
</package>
</packages>
</coverage>