XUnit (and NUNIT - see last paragraph) Test Projects come with a NuGet plugin Coverlet.Collector:
This doesn't need to be installed in any project, all you need to do is run these steps that I've made into a Powershell script:
ExecCodeCoverage.ps1
# PURPOSE: Automates the running of Unit Tests and Code Coverage
# REF: https://mcmap.net/q/196420/-how-to-get-code-coverage-from-unit-tests-in-visual-studio-2022-community-edition
# If running outside the test folder
#cd E:\Dev\XYZ\src\XYZTestProject
# This only needs to be installed once (globally), if installed it fails silently:
dotnet tool install -g dotnet-reportgenerator-globaltool
# Save currect directory into a variable
$dir = pwd
# Delete previous test run results (there's a bunch of subfolders named with guids)
Remove-Item -Recurse -Force $dir/TestResults/
# Run the Coverlet.Collector - REPLACING YOUR SOLUTION NAME!!!
$output = [string] (& dotnet test ../YOURSOLUTIONNAME.sln --collect:"XPlat Code Coverage" 2>&1)
Write-Host "Last Exit Code: $lastexitcode"
Write-Host $output
# Delete previous test run reports - note if you're getting wrong results do a Solution Clean and Rebuild to remove stale DLLs in the bin folder
Remove-Item -Recurse -Force $dir/coveragereport/
# To keep a history of the Code Coverage we need to use the argument: -historydir:SOME_DIRECTORY
if (!(Test-Path -path $dir/CoverageHistory)) {
New-Item -ItemType directory -Path $dir/CoverageHistory
}
# Generate the Code Coverage HTML Report
reportgenerator -reports:"$dir/**/coverage.cobertura.xml" -targetdir:"$dir/coveragereport" -reporttypes:Html -historydir:$dir/CoverageHistory
# Open the Code Coverage HTML Report (if running on a WorkStation)
$osInfo = Get-CimInstance -ClassName Win32_OperatingSystem
if ($osInfo.ProductType -eq 1) {
(& "$dir/coveragereport/index.html")
}
Put it in the TestProject:
^ Right click Run with Powershell
The results are quite good (for FREE):
You can drill down to see the highlighted line coverage, its just not as powerful or integrated as the Enterprise Edition:
I updated the script to support History as well:
'
NUnit UPDATE: This script works with NUNit as well, simply include these references:
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2" />
<PackageReference Include="GenFu" Version="1.6.0" />
<PackageReference Include="Moq" Version="4.18.2" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="NunitXml.TestLogger" Version="3.0.127" />
<PackageReference Include="ReportGenerator" Version="5.1.10" />
</ItemGroup>
Tools > Options > Fine Code Coverage > AdjacentBuildOutput to true
. – Flitting