Bazel 包含一个 coverage
子命令,用于生成可通过 bazel coverage
进行测试的代码库的代码覆盖率报告。鉴于各种语言生态系统的特点,为给定项目开展这项工作并不总是那么简单。
本页面记录了创建和查看覆盖率报告的一般过程,并提供了一些关于配置已知语言的特定语言的备注。您最好先阅读常规部分,然后了解特定语言的要求。另请注意远程执行部分,这需要注意一些其他事项。
尽管可以进行很多自定义,但本文档重点介绍如何使用 lcov
报告,该报告目前是受支持程度最高的路由。
创建覆盖率报告
准备工作
创建覆盖率报告的基本工作流需要满足以下要求:
- 包含测试目标的基本代码库
- 安装了特定于语言的代码覆盖率工具的工具链
- “插桩”配置正确无误
前两种语言因语言而异,通常比较简单,但对于复杂的项目而言,后者可能更困难。
在本例中,“插桩”是指用于特定目标的覆盖率工具。Bazel 允许使用 --instrumentation_filter
标志为文件的特定子集开启此功能,该标志指定使用插桩测试的目标的过滤条件已启用。如需为测试启用插桩功能,必须使用 --instrument_test_targets
标志。
默认情况下,Bazel 会尝试匹配目标软件包,并将相关过滤器输出为 INFO
消息。
运行覆盖率
要生成覆盖率报告,请使用 bazel coverage
--combined_report=lcov
[target]
。这会对目标运行测试,并为每个文件生成 lcov 格式的覆盖率报告。
完成后,Bazel 会运行收集所有生成的覆盖率文件的操作,然后将它们合并成一个,然后再在 $(bazel info
output_path)/_coverage/_coverage_report.dat
下创建。
如果测试失败,系统也会生成覆盖率报告,但请注意,这不适用于失败的测试 - 系统只会报告通过的测试。
查看覆盖率
覆盖率报告仅以非人类可读的 lcov
格式输出。在这里,我们可以使用 genhtml
实用程序(lcov 项目的一部分)来生成可以在网络浏览器中查看的报告:
genhtml --output genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"
请注意,genhtml
也会读取源代码,以注释这些文件中缺少的范围。为此,应在 Bazel 项目的根目录中执行 genhtml
。
要查看结果,只需在任何网络浏览器中打开 genhtml
目录中生成的 index.html
文件。
如需获得有关 genhtml
工具或 lcov
覆盖率格式的进一步帮助和信息,请参阅 lcov 项目。
远程执行
目前使用远程测试执行功能需要注意以下几点:
- 报告组合操作尚无法远程运行。这是因为 Bazel 不会将覆盖率输出文件视为其图的一部分(请参阅此问题),因此不能将其正确视为组合的输入操作。如需解决此问题,请使用
--strategy=CoverageReport=local
。- 注意:如果 Bazel 设置为试用
local,remote
,则可能需要指定类似--strategy=CoverageReport=local,remote
的内容,具体取决于 Bazel 解析策略的方式。
- 注意:如果 Bazel 设置为试用
--remote_download_minimal
和类似标志也不能用作前者的结果。- 如果先前已缓存测试,Bazel 当前将无法创建覆盖率信息。为了解决此问题,可以单独为覆盖率运行设置
--nocache_test_results
,但当然,这会在测试方面产生沉重的成本。 --experimental_split_coverage_postprocessing
和--experimental_fetch_all_coverage_outputs
- 覆盖率通常在测试操作过程中运行,因此默认情况下,我们无法将所有覆盖率作为远程执行的输出返回。这些标志会替换默认值并获取覆盖率数据。如需了解详情,请参阅此问题。
特定语言的配置
Java
Java 应可以直接使用默认配置。Bazel 工具链包含远程执行所需的所有内容,包括 JUnit。
Python
前提条件
使用 Python 运行覆盖率需要满足以下前提条件:
- 包含 b01c859 的 Bazel 二进制文件,该文件应为任何 Bazel 3.0 及以上。
- 改良版 coverage.py。
使用修改后的 coverage.py
为此,您可以使用rules_python ,以便让您能够使用requirements.txt
然后使用pip_install代码库规则。
requirements.txt
应具有以下条目:
git+https://github.com/ulfjack/coveragepy.git@lcov-support
然后,在工作区文件中应使用 rules_python
、pip_install
和 requirements.txt
文件,如下所示:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_python",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.5.0/rules_python-0.5.0.tar.gz",
sha256 = "cd6730ed53a002c56ce4e2f396ba3b3be262fd7cb68339f0377a45e8227fe332",
)
load("@rules_python//python:pip.bzl", "pip_install")
pip_install(
name = "python_deps",
requirements = "//:requirements.txt",
)
然后,通过在 BUILD
文件中设置以下内容,测试目标可以使用 coverage.py 的要求:
load("@python_deps//:requirements.bzl", "entry_point")
alias(
name = "python_coverage_tools",
actual = entry_point("coverage"),
)
py_test(
name = "test",
srcs = ["test.py"],
env = {
"PYTHON_COVERAGE": "$(location :python_coverage_tools)",
},
deps = [
":main",
":python_coverage_tools",
],
)