blob: 8c162d86fdb391f2e0da8ea27fbb5fd4515cb1e0 [file] [view]
# Setting up coverage
As of Bazel 6, the Python toolchains and bootstrap logic supports providing
coverage information using the `coverage` library.
As of `rules_python` version `0.18.1`, builtin coverage support can be enabled
when configuring toolchains.
## Enabling `rules_python` coverage support
Enabling the coverage support bundled with `rules_python` just requires setting an
argument when registering toolchains.
For Bzlmod:
```starlark
python.toolchain(
"@python3_9_toolchains//:all",
configure_coverage_tool = True,
)
```
For WORKSPACE configuration:
```starlark
python_register_toolchains(
register_coverage_tool = True,
)
```
:::{note}
This will implicitly add the version of `coverage` bundled with
`rules_python` to the dependencies of `py_test` rules when `bazel coverage` is
run. If a target already transitively depends on a different version of
`coverage`, then the behavior is undefined -- it is undefined which version comes
first in the import path. If you find yourself in this situation, then you'll
need to manually configure coverage (see below).
:::
:::{note}
The bundled `coverage` wheel set covers CPython 3.9 through 3.14 (with
freethreaded variants for 3.13+), and not every platform within that range.
When the interpreter that `bazel coverage` actually selects has no bundled
wheel, `configure_coverage_tool = True` produces no coverage tool and
`bazel coverage` emits empty lcov data; manually configure coverage (see
below) instead.
`py_runtime` warns when this happens. The warning is emitted during analysis,
for the runtime toolchain resolution selected and only when coverage is being
collected, so it does not fire for the many platforms toolchains are
registered for but a given build never uses.
:::
## Manually configuring coverage
To manually configure coverage support, you'll need to set the
`py_runtime.coverage_tool` attribute. This attribute is a target that specifies
the coverage entry point file and, optionally, client libraries that are added
to `py_test` targets. Typically, this would be a `filegroup` that looked like:
```starlark
filegroup(
name = "coverage",
srcs = ["coverage_main.py"],
data = ["coverage_lib1.py", ...]
)
```
Using `filegroup` isn't required, nor are including client libraries. The
important behaviors of the target are:
* It provides a single output file OR it provides an executable output; this
output is treated as the coverage entry point.
* If it provides runfiles, then `runfiles.files` are included into `py_test`.