C# 单元测试覆盖率方法 C#如何查看代码的测试覆盖率

来源:这里教程网 时间:2026-02-21 17:41:09 作者:

Visual Studio 自带的测试覆盖率怎么开

Visual Studio 2019 及以上版本(含 Community 版)已内置测试覆盖率功能,但默认不显示——需要手动触发。关键不是装插件,而是跑测试时带上覆盖率采集开关。

确保项目是 .NET Framework 或 .NET Core/.NET 5+(.NET Core 3.1+ 支持更稳定) 测试项目需引用
Microsoft.NET.Test.Sdk
,且使用
dotnet test
或 VS 的“测试资源管理器”运行
在 VS 中:点击菜单栏 测试 → 分析代码覆盖率 → 所有测试(或右键单个测试 → “分析代码覆盖率”) 首次运行后,底部状态栏会出现“代码覆盖率”窗口,双击文件可跳转到具体行——未覆盖的行会标灰

dotnet cli 下用 coverlet 生成覆盖率报告

VS 内置工具对 .NET Core/.NET 5+ 项目有时识别不全(尤其多项目、自定义 SDK 时),coverlet 是目前最稳的跨平台方案,输出格式也更灵活。

在测试项目中添加 NuGet 包:
Coverlet.Collector
(注意不是
Coverlet.MsBuild
,后者已过时)
命令行执行:
dotnet test --collect:"XPlat Code Coverage"
会生成
coverage.cobertura.xml
文件;可用
reportgenerator
转 HTML:
dotnet tool install -g dotnet-reportgenerator-globaltool
,再运行
reportgenerator "-reports:coverage.cobertura.xml" "-targetdir:coveragereport"
打开
coveragereport/index.html
即可交互查看——支持按类、方法、行级展开

为什么某些代码没被计入覆盖率

不是所有“写了代码”就自动参与统计,coverlet 和 VS 都遵循 ECMA-335 标准的 IL 级别采样逻辑,常见漏计原因很具体:

async void
方法不会被覆盖(应改用
async Task
属性的
get
/
set
如果是编译器自动生成(
{ get; set; }
),默认不计入——但显式实现的访问器会记
构造函数里调用
base(...)
this(...)
的那一行,部分版本 coverlet 不采样(不影响整体分支覆盖率)
条件编译块(如
#if DEBUG
)在非对应配置下根本不会生成 IL,自然无覆盖率数据

CI 环境中如何稳定获取覆盖率数值

GitHub Actions / Azure Pipelines 等场景下,不能依赖 VS GUI,必须靠 CLI 输出结构化结果,并提取关键指标用于门禁(如“覆盖率低于 70% 则失败”)。

dotnet test --collect:"XPlat Code Coverage" --settings coverlet.runsettings
,其中
coverlet.runsettings
可指定
<include></include>
<exclude></exclude>
模式(例如排除
*Tests.dll
*.Generated.cs
dotnet tool install -g dotnet-coverage
(.NET 6+ 原生工具),再运行
dotnet-coverage collect "dotnet test"
,最后
dotnet-coverage report -f cobertura
关键点:所有路径必须用相对路径,且 CI agent 的工作目录要和
.csproj
同级,否则
coverlet
可能找不到源码映射
实际项目里最容易卡住的是路径匹配和多目标框架(
<targetframeworks>net6.0;netstandard2.0</targetframeworks>
)——coverlet 默认只测第一个框架,得加
--framework net6.0
显式指定。

相关推荐