LCOV 使用文档
LCOV 使用文档
摘要
LCOV 是一个用于操作和显示程序在运行特定测试用例或测试用例集时哪些部分被执行(即“覆盖”)的工具。LCOV 由一组 Perl 脚本组成,这些脚本基于各种覆盖率工具(例如 gcov、llvm-cov、Coverage.py、Cobertura、Devel::Cover、Jacoco 等)的文本输出,实现了以下增强功能:
- HTML 输出:使用条形图和特定颜色在超链接的覆盖率报告中指示覆盖率,旨在使用户能够快速诊断和解决覆盖率问题。
- 支持大型项目:概览页面允许通过提供分层目录结构视图、项目中所有源文件的平面列表或三级详细视图(目录、文件和源代码视图)快速浏览覆盖率数据。
- 支持多种语言:包括 C/C++、Perl 和 Python。
LCOV 最初是为支持 Linux 内核覆盖率测量而设计的,但也适用于标准用户空间应用程序的覆盖率测量。
LCOV 支持差异覆盖率,以及日期和所有者分箱。有关概念和几种可能使用模型的详细解释,请参阅:
- https://arxiv.org/abs/2008.07947
- https://ieeexplore.ieee.org/document/9438597
基本思想的视频演示可以在以下网址找到:
- http://doi.org/10.5281/zenodo.4653252
此外,还提供了其他一些功能和能力。有关简要说明,请参阅下面的第 6 节,也可以参阅手册页和测试用例。
目录
- 包含的文件
- 安装 LCOV
- 依赖项
- 访问 Linux 内核覆盖率数据的示例
- 访问用户空间程序覆盖率数据的示例
- LCOV 功能
- 问题和评论
- 提交新问题
1. 重要文件
- README:本 README 文件
- CHANGES:各版本之间的更改列表
- bin/lcov:用于捕获 LCOV 覆盖率数据的工具
- bin/genhtml:用于从 LCOV 数据创建 HTML 输出的工具
- bin/gendesc:用于创建 genhtml 使用的描述文件的工具
- bin/perl2lcov:用于将 Perl Devel::Cover 数据转换为 lcov 格式的工具
- bin/llvm2lcov:用于将 LLVM ‘llvm-cov’ JSON 数据转换为 LCOV 格式的工具
- bin/py2lcov:用于将 Python Coverage.py 数据转换为 lcov 格式的工具
- bin/xml2lcov:用于将类似 Cobertura 的 XML 覆盖率数据转换为 lcov 格式的工具
- bin/geninfo:内部工具(创建 LCOV 数据文件)
- bin/genpng:内部工具(创建源文件的 png 概览)
- lcovrc:LCOV 配置文件
- man:包含所包含工具的手册页的目录
- example:包含演示 LCOV 的示例的目录
- tests:包含 LCOV 回归测试的目录
- Makefile:提供 ‘install’ 和 ‘uninstall’ 目标的 Makefile
2. 安装 LCOV
LCOV 包可以从以下网址以 RPM 或 tarball 的形式获得:
- https://github.com/linux-test-project/lcov/releases
要安装 tarball,请将其解压到目录中并运行:
make install
使用 Git 获取最新(但可能不稳定)版本:
git clone https://github.com/linux-test-project/lcov.git
切换到生成的 lcov 目录并输入:
make install
默认安装位置是 /usr/local。请注意,您可能需要具有超级用户权限才能写入系统目录。
要安装在不同位置(例如,您的主目录),请运行:
make PREFIX=$HOME/my_lcov install
您的 PREFIX 应该是绝对路径。
要运行 LCOV 回归测试套件以测试您的安装:
$ cp -r $LCOV_HOME/share/test path/to/myTestDir
$ cd path/to/myTestDir
$ make [COVERAGE=1]
如果需要,您可以通过设置 COVERAGE makefile 变量来收集 LCOV 模块的覆盖率数据。
请注意,如果启用了 COVERAGE 或者您想要使用 perl2lcov 工具,则必须安装 Devel::Cover 包。
要查看收集的覆盖率信息,请在运行测试后将浏览器指向 …/lcov_coverage/index.html。
请注意,测试用例主要是为了测试 LCOV 功能,并不是易于阅读的教程示例。
3. 依赖项
LCOV 模块主要用 Perl 实现,需要一个相对最新的 Perl 安装和多个 Perl 包。
这些 Perl 包包括:
- Capture::Tiny
- DateTime
- Devel::Cover
- Digest::MD5
- File::Spec
- 至少一种 JSON 模块。按性能/偏好的顺序:
- JSON::XS
- Cpanel::JSON::XS
- JSON::PP
- JSON
- Memory::Process
- Module::Load::Conditional
- Scalar::Util
- Time::HiRes
- TimeDate
如果您的系统缺少其中任何一个,您可以通过以下方式安装它们:
$ perl -MCPAN -e 'install(<packageName>)'
您很可能需要超级用户权限才能安装 Perl 模块。
LCOV 模块提供的一些应用程序是用 Python 编写的,可能需要额外的 Python 包。
特别是,要生成任何电子表格报告,需要 ‘xlsxwriter’。
要测量 Python 代码覆盖率,用户需要 Python 包:
- Coverage.py
此外,贡献者还需要:
- perltidy
您的平台可能支持其他机制来安装和/或更新所需的包。
4. 访问 Linux 内核覆盖率数据的示例
要求:请按照 Linux 内核覆盖率设置说明操作:
- https://docs.kernel.org/dev-tools/gcov.html
作为 root 用户,请执行以下操作:
a) 重置计数器
lcov --zerocounters
b) 将当前覆盖率状态捕获到文件中
lcov --capture --output-file kernel.info
c) 获取 HTML 输出
genhtml kernel.info
将您选择的网页浏览器指向生成的 index.html 文件。
5. 访问用户空间程序覆盖率数据的示例
a) 将当前覆盖率状态捕获到文件中:
i) C/C++ 代码:
使用 GCC 或 LLVM 的 ‘–coverage’ 选项编译您的程序。在链接期间,确保指定 ‘–coverage’:
$ gcc -o myTest --coverage simple.c或
$ gcc -c file1.c file2.c ... --coverage
$ gcc -o myOtherTest --coverage file1.o file2.o ....
或者,LLVM 用户可以使用 ‘profdata path’(而不是 ‘gcov path’)来收集 C/C++ 代码的覆盖率数据。有关详细信息,请参阅:
- https://github.com/linux-test-project/lcov/discussions/234
运行您的测试用例至少一次:
$ path/to/my/testcase/myTest
将当前覆盖率状态捕获到文件中:
$ lcov --directory path/to/my/testcase --capture --output-file app.info
(使用 ‘profdata path’ 的 LLVM 用户在此步骤将使用略有不同的命令 - 请参阅上述讨论。)
如果您想要收集修改条件/决策覆盖率(MD/DC)数据,那么:
- 您必须使用 gcc/14.2(或更新版本),或 LLVM/18(或更新版本)
- 您的 GCC 编译和链接命令行必须包含标志 ‘-fcondition-coverage’。
- LLVM 用户必须使用 ‘profdata path’ 来收集覆盖率数据,您的编译命令行必须包含 ‘-fprofile-inst-generate -fcoverage-mapping -fcoverage-mcdc’。请参阅上述讨论以获取详细信息。
- 您的 lcov 和 genhtml 命令行必须包含标志 ‘–mcdc-coverage’
请参阅 genhtml 和 geninfo 手册页中的 ‘–mcdc-coverage’ 部分。
请注意,运行时覆盖率数据仅在应用程序启动并停止至少一次后存在。否则,将找不到数据,lcov 将会因提到没有 data/.gcda 文件而中止。
覆盖率运行时在 atexit 回调中发出数据(.gcda 文件)。如果您的应用程序在回调执行之前异常退出或崩溃,则不会提供覆盖率数据。
有关 gcc 个人资料机制的详细信息,请参阅 gcov 手册页。
有关详细信息,请参阅 ‘man lcov’ - 尤其是如果您的构建/测试环境不简单的话。
ii) Python 代码:
- 安装 Coverage.py 模块
- 执行您的测试用例以生成 python 覆盖率数据:
$ COVERAGE_FILE=./pycov.dat coverage run --append --branch \myPythonScript [my script args]
- 将 Python 覆盖率数据转换为 LCOV 格式:
$ py2lcov -o pycov.info [py2lcov_options] pycov.dat [x.dat]+
有关详细信息,请参阅 ‘py2lcov --help’ 和 Coverage.py 文档。
iii) Perl 代码:
- 安装 Devel::Cover 模块
- 执行您的测试用例以生成 perl 覆盖率数据:
$ perl -MDevel::Cover=-db,perlcov_db,-coverage,statement,branch,condition,subroutine,-silent,1 myPerlTest.pl [my script args]
- 将 Perl 覆盖率数据转换为 LCOV 格式:
$ perl2lcov --output perlcov.info perlcov_db [perl2lcov options]
有关详细信息,请参阅 ‘perl2lcov --help’ 和 Devel::Cover 文档。
iv) XML 数据(例如,由 Cobertura 生成):
- 将 XM 覆盖率数据转换为 LCOV 格式:
$ xml2lcov --output myData.info coverage.xml [xml2lcov options]
有关详细信息,请参阅 ‘xml2lcov --help’ 和 Cobertura 文档。
b) 生成 HTML 覆盖率报告:
生成 HTML 报告,合并所有 LCOV 数据文件:
$ genhtml -o html_report app.info pycov.info perlcov.info
将您选择的网页浏览器指向生成的文件:
html_report/index.html
有关详细信息,请参阅 ‘man genhtml’。
c) 生成差异覆盖率报告:
请参阅 …/example(运行 “make test_differential”)以及 …/tests/gendiffcov 中的示例。
6. LCOV 功能
LCOV 的功能和能力分为 7 个主要类别:
a) 分类
这主要涉及差异覆盖率分类以及日期和所有者分箱。有关概念的详细描述,请参阅:
- https://arxiv.org/abs/2008.07947
- https://ieeexplore.ieee.org/document/9438597
差异分类和分箱是正交的,这意味着您可以生成差异报告而不进行分箱,也可以生成带有分箱的“普通”覆盖率报告。有关详细信息,请参阅上述论文和 genhtml 手册页。
相关选项:
–baseline-file, --diff-file, --annotate-script, --select-script, --date-bins, --date-labels, --new-file-as-baseline, --elide-path-mismatch
b) 错误处理
lcov 工具套件中添加了一个通用但非常简单的错误处理程序。错误处理程序用于报告异常,并为用户提供一个忽略特定消息的机制。请注意,忽略某些错误可能会导致后续错误和/或导致不一致或令人困惑的覆盖率报告。
有关详细信息,请参阅 genhtml/lcov/geninfo 手册页。
请注意,某些错误是不可恢复的 - 不能被抑制或忽略。
相关选项:
–ignore-error, --expect-message-count, --keep-going, --msg-log
c) 导航和显示
已实现诸如指向第一个未覆盖区域的超链接、指向下一个未覆盖区域的超链接等导航辅助功能。同样,新表格、新列以及表格之间的新链接使用户能够识别特定代码的作者(已覆盖或未覆盖),以及代码编写的时间。
这些功能共同帮助用户快速识别代码覆盖率问题的原因,然后决定如何处理。
还可以生成遵循源代码目录结构的“分层”覆盖率报告或“平面”报告(所有文件位于两级报告的顶层),以及各种其他小功能(工具提示弹出窗口、用户指定的 HTML 标题、页脚和表格标签等)。
有关详细信息,请参阅 genhtml 手册页,以及 ‘gendiffcov/simple’ 测试用例中的示例。
相关选项:
–baseline-title, --baseline-date, --current-date, --flat, --hierarchical, --show-owners, --show-noncode, --show-navigation, --show-proportion, --suppress-aliases
d) 数据操作
过滤器用于抑制或删除某些覆盖率伪影 - 例如,编译器生成的分支(例如,用于异常处理)。这些伪影可能会淹没用户代码并掩盖用户感兴趣的覆盖率特征。
其他选项用于关注或排除代码的某些部分,以及进行文件名的正则表达式替换 - 可能使用不区分大小写的比较。(当构建结构与您的修订控制系统中的布局不完全匹配时,路径处理特别有用;这在具有可重用组件的大型项目中很常见。)
在捕获覆盖率数据时,可以使用 --build-directory 选项指定搜索路径,以找到与特定 .gcda(运行时覆盖率数据)文件对应的 .gcno(编译时覆盖率数据)文件。同样,可以使用 --source-directory 选项指定源文件的搜索路径。
有关可用过滤器和操作功能的详细描述,请参阅 lcov/geninfo/genhtml 手册页。
相关选项:
–include, --exclude, --erase-functions, --omit-lines, --substitute, --filter, --build-directory, --source-directory
e) 回调/自定义
用户可以提供回调,用于:
i) 与修订控制系统接口
示例脚本:
- Perforce:请参阅 ‘p4diff’、‘p4annotate.pm’、‘p4annotate’
- Git:请参阅 ‘gitdiff’、‘gitblame.pm’、‘gitblame’
ii) 验证源代码版本是否兼容,并
示例脚本:请参阅 ‘get_signature’、‘P4version.pm’、‘getp4version’、‘gitversion’、‘gitversion.pm’ 和 ‘batchGitVersion.pm’
iii) 强制执行所需的代码覆盖率标准
示例脚本:criteria.pm/criteria
iv) 在更复杂的环境中查找源文件 - 在这些环境中,简单的替换变得复杂或笨拙。
v) 选择要显示的覆盖率数据的子集 - 例如,用于仅关注由特定提交或提交范围引起的更改的代码审查,或用于审查特定版本中的更改。
示例脚本:select.pm
vi) 跟踪环境和其他设置 - 以帮助复杂使用案例中的基础设施调试。
回调可以是任何所需的脚本或可执行文件 - 但如果将其编写为 Perl 模块,则可能会有性能优势。
有关详细信息,请参阅 genhtml/lcov/geninfo 手册页。
请注意,各种示例脚本位于源代码的 ‘scripts’ 目录中,但在发布版的 $LCOV_HOME/share/lcov/support-scripts 目录中安装。
相关选项:
–annotate-script, --criteria-script, --version-script, --resolve-script, --select-script, --context-script
f) 性能
lcov/genhtml/geninfo 已重构为在请求时跨多个内核并行计算。通常,这提供了几乎与内核数量成线性的加速。
还有一个选项可以限制并行性以不超过峰值内存消耗限制,以及启用简单的配置文件数据收集的选项 - 这样您可以看到时间花在哪里,从而提示潜在的优化。‘spreadsheet.py’ 脚本可用于查看生成的配置文件数据。
有几个配置文件选项可用于调整某些并行化参数,以优化您的环境的性能,在默认行为不理想的情况下。有关详细信息,请参阅 lcovrc 手册页。
有关详细信息,请参阅 genhtml/lcov/geninfo 手册页。
相关选项:–parallel, --memory, --profile
g) 语言/工具支持
添加了 ‘llvm2lcov’、‘py2lcov’、‘perl2lcov’ 和 ‘xml2lcov’ 脚本。
-
llvm2lcov:
将 ‘llvm-cov export -format=text …’ 生成的 JSON 覆盖率数据转换为 lcov 格式。
有关如何使用转换器的简要说明,请参阅 “llvm2lcov --help”。请注意,llvm2lcov 使用的命令行和配置文件选项与 lcov、genhtml 和 geninfo 类似。 -
py2lcov:
将 python Coverage.py XML 数据转换为 lcov 格式。
有关详细信息,请参阅 Coverage.py 文档 ,以及 “…/py2lcov --help”。 -
perl2lcov:
将 Perl Devel::Cover 数据转换为 lcov 格式。
有关如何为 Perl 代码生成覆盖率数据,请参阅 Devel::Cover 文档。
有关如何使用转换器的简要说明,请参阅 “perl2lcov --help”。请注意,perl2lcov 使用的命令行和配置文件选项与 lcov、genhtml 和 geninfo 类似。 -
xml2lcov:
将 XML 覆盖率数据转换为 lcov 格式。XML 数据可能来自 Cobertura 或类似工具。
有关如何使用转换器的简要说明,请参阅 “xml2lcov --help”。有关如何生成 XML 数据,请参阅 Cobertura 文档。
可以使用类似的方法集成其他语言。
通常,lcov、genhtml 和 geninfo 中统一实现了新功能和选项。大多数功能可以通过命令行选项或在 ‘lcovrc’ 文件中设置默认值来启用/禁用。有关详细信息,请参阅 lcovrc 手册页。
7. 问题和评论
有关如何使用 LCOV 工具的详细信息,请参阅所包含的手册页。
如有其他问题,请随时在 LCOV 代码库的 issue tracker 上提交新问题或讨论:
- https://github.com/linux-test-project/lcov
8. 提交新问题
在提交新问题之前 - 如果您使用的是 LCOV 发行版(而不是 github 仓库的克隆版) - 请验证该问题是否仍然存在于 LCOV master 版本中。有关如何克隆和安装最新 LCOV 版本的说明,请参阅上面的第 2 节。
如果可能,请在提交问题时包含一个演示问题的测试用例。
请描述您的环境(平台、编译器、perl 和 python 版本等)。请包含对该问题的详细描述:您的目标是什么(您的目标 - 而不是您的操作步骤),您的操作步骤(您的操作步骤),您希望看到的结果与实际发生的结果。
根据问题的不同,您的测试用例可能需要包含源代码和编译/链接命令行、如何运行示例的说明、用于捕获和生成 LCOV 报告的命令行等。
在其他情况下,捕获的 ‘.info’ 文件可能足以重现问题。
如有疑问:多提供信息总比少提供好。
如果您无法包含测试用例 - 例如,因为您认为它是敏感或专有的 - 那么您的详细描述就更加重要。
请注意,如果没有示例,可能很难或无法诊断或解决问题。
请记住,您是在请求志愿者的帮助。您的优先级可能不是他们的优先级。文明、体贴和礼貌非常重要。
请回来看看并验证问题已解决后关闭问题。
再次提醒:您是在请求志愿者的帮助。请确保您尽到了自己的责任。