排查代码覆盖率问题
适用于: Visualstudio
Visual Studio 中的代码覆盖率分析工具收集本机和托管程序集的数据, (.dll 或 .exe 文件) 。 但是,在某些情况下,“ 代码覆盖率结果” 窗口显示类似于“生成的空结果:...”的错误。 本文可帮助你排查和解决可能遇到空结果的各种原因。
应该看到什么?
如果在“测试”菜单中选择“分析代码覆盖率”命令,并且生成和测试成功运行,则应在“代码覆盖率”窗口中看到结果列表。 可能需要展开项才能查看详细信息。
有关详细信息,请参阅 使用代码覆盖率来确定要测试的代码量。
看不到任何结果或旧结果的可能原因
你未使用正确版本的 Visual Studio
需要Visual Studio Enterprise。
未执行任何测试
分析
检查输出窗口。 在 “显示来自的输出 ”下拉列表中,选择“ 测试”。 查看是否记录了任何警告或错误。
说明
代码覆盖率分析是在测试运行时完成的。 它仅包括运行测试时加载到内存中的程序集。 如果未执行任何测试,则代码覆盖率无法报告。
解决方案
在“测试资源管理器”中,选择“ 全部运行” 以验证测试是否成功运行。 在使用 “分析代码覆盖率”之前修复所有失败。
你正在查看以前的结果
修改并重新运行测试时,以前的代码覆盖率结果仍可见,包括旧运行中的代码着色。 请按照以下步骤解决此问题:
- 运行 “分析代码覆盖率”。
- 确保在“ 代码覆盖率 结果”窗口中选择了最新结果集。
.pdb (符号) 文件不可用
分析
打开编译目标文件夹 (通常为 bin\debug) ,并验证每个程序集是否与 .dll 或 .exe 文件位于同一目录中的 .pdb 文件。
说明
代码覆盖率引擎要求每个程序集在测试运行期间具有可访问其关联的 .pdb 文件。 如果特定程序集没有 .pdb 文件,则不会分析该程序集。
.pdb 文件必须从与.dll 或 .exe 文件相同的生成生成。
解决方案
确保生成设置生成 .pdb 文件。
如果在生成项目时未更新 .pdb 文件,请打开项目属性,选择“ 生成 ”页,选择“ 高级”,然后检查 “调试信息”。
在 Visual Studio 2022 及更高版本中,对于面向 .NET Core 或 .NET 5+ 的 C# 项目,打开项目属性,选择“ 生成 ”选项卡,选择“ 常规”,然后检查 调试符号。
对于 C++ 项目,请确保生成的 .pdb 文件具有完整的调试信息。 打开项目属性,并验证 链接器>调试>生成调试信息 是否设置为 “生成调试信息”,该信息针对 /DEBUG:FULL (/DEBUG:FULL) 进行共享和发布 优化。
如果 .pdb 和 .dll 或 .exe 文件位于不同的位置,请将 .pdb 文件复制到同一个目录。 还可以将代码覆盖率引擎配置为在另一个位置搜索 .pdb 文件。 有关详细信息,请参阅 自定义代码覆盖率分析。
使用已检测或优化的二进制文件
分析
确定二进制文件是经过任何形式的高级优化(如配置文件引导优化),还是已由分析工具(如 vsinstr.exe 或 vsperfmon.exe)进行检测。
说明
如果程序集已由另一个分析工具检测或优化,则代码覆盖率分析中将省略该程序集。 无法对此类程序集执行代码覆盖率分析。
解决方案
关闭优化并使用新版本。
代码不是托管的 (.NET) 或本机 (C++) 代码
分析
确定是针对托管代码还是 C++ 代码运行一些测试。
说明
Visual Studio 中的代码覆盖率分析仅适用于托管和本机 (C++) 代码。 如果使用第三方工具,部分或全部代码可能会在不同的平台上执行。
解决方案
无可用。
项目名称包括“DataCollector”
在项目名称中使用 DataCollector 的项目不会通过代码覆盖率进行标识。
NGen 已安装程序集
分析
确定是否从本机映像缓存加载程序集。
说明
出于性能原因,不会分析本机映像程序集。 有关详细信息,请参阅 Ngen.exe (本机映像生成器) 。
解决方案
使用程序集的 MSIL 版本。 请勿使用 NGen 处理它。
自定义 .runsettings 文件存在语法问题
分析
如果使用自定义 .runsettings 文件,它可能包含语法错误。 代码覆盖率未运行,代码覆盖率窗口在测试运行结束时未打开,或者显示旧结果。
说明
可以使用自定义 .runsettings 文件运行单元测试,以配置代码覆盖率选项。 这些选项允许包含或排除文件。 有关详细信息,请参阅 自定义代码覆盖率分析。
解决方案
有两种可能的故障类型:
XML 错误
在 Visual Studio XML 编辑器中打开 .runsettings 文件。 查找错误指示。
正则表达式错误
文件中的每个字符串都是一个正则表达式。 查看每个错误,并特别查找:
- 不匹配的括号 (...) 或未转义的括号 \ (...\) 。 如果要匹配搜索字符串中的括号,则必须对其进行转义。 例如,若要匹配函数,请使用:
.*MyFunction\(double\)
- 表达式开头的星号或加号。 若要匹配任何字符串字符,请使用后跟星号的点:
.*
- 不匹配的括号 (...) 或未转义的括号 \ (...\) 。 如果要匹配搜索字符串中的括号,则必须对其进行转义。 例如,若要匹配函数,请使用:
包含错误排除项的自定义 .runsettings 文件
分析
如果使用自定义 .runsettings 文件,请确保该文件包含程序集。
说明
可以使用自定义 .runsettings 文件运行单元测试,以配置代码覆盖率选项。 这些选项允许包含或排除文件。 有关详细信息,请参阅 自定义代码覆盖率分析。
解决方案
从 .runsettings 文件中删除所有Include
节点,然后删除所有Exclude
节点。 如果这解决了问题,请将它们放回各个阶段。
确保 DataCollectors 节点指定“代码覆盖率”。 将其与 自定义代码覆盖率分析中的示例进行比较。
某些代码始终显示为未涵盖
在检测之前执行本机 DLL 中的初始化代码
分析
在静态链接的本机代码中,部分初始化函数 DllMain 及其调用的代码有时显示为未涵盖,即使已执行代码也是如此。
说明
代码覆盖率工具的工作原理是,在应用程序开始运行之前将检测插入程序集。 在事先加载的任何程序集中, DllMain 中的初始化代码在加载程序集时和应用程序运行之前立即执行。 似乎未涵盖该代码,这通常适用于静态加载的程序集。
解决方案
无。