Bazel cuenta con un subcomando coverage
para producir cobertura de código.
Informes sobre repositorios que se pueden probar con bazel coverage
. Venc.
a las idiosincrasias de los diversos ecosistemas lingüísticos,
siempre es trivial para que esto funcione en un proyecto determinado.
En esta página, se documenta el proceso general de creación y visualización informes de cobertura y también incluye algunas notas específicas del idioma para lenguajes de programación cuya configuración es conocida. Se recomienda leer primero leer la sección general y, luego, leyendo sobre los requisitos de un lenguaje específico. Ten en cuenta también sección de ejecución remota, que requiere consideraciones adicionales.
Si bien es posible realizar una gran cantidad de personalización, este documento se centra en
produce y consume informes de lcov
, que actualmente es el
la ruta más compatible.
Cómo crear un informe de cobertura
Preparación
El flujo de trabajo básico para crear informes de cobertura requiere la lo siguiente:
- Un repositorio básico con objetivos de prueba
- Una cadena de herramientas con las herramientas de cobertura de código específicas del lenguaje instaladas
- Una “instrumentación” correcta configuración
Las dos primeras son específicas del lenguaje y, en su mayoría, sencillas, Sin embargo, este último puede ser más difícil en proyectos complejos.
"Instrumentación" en este caso, a las herramientas de cobertura
usarse para un objetivo específico. Bazel permite activar esta función para un
subconjunto específico de archivos con el
--instrumentation_filter
marca, que especifica un filtro para los objetivos que se prueban con el
instrumentación habilitada. Para habilitar la instrumentación para pruebas,
--instrument_test_targets
es obligatoria.
De forma predeterminada, bazel intenta hacer coincidir los paquetes de destino y, luego, imprime los
relevante como un mensaje INFO
.
Cobertura para correr
Para crear un informe de cobertura, usa bazel coverage
--combined_report=lcov
[target]
. Esto ejecuta el
pruebas para la orientación y la generación de informes de cobertura en formato lcov
para cada archivo.
Cuando termina, Bazel ejecuta una acción que recopila todo lo que
archivos de cobertura y los combina en uno, que finalmente
creada con $(bazel info
output_path)/_coverage/_coverage_report.dat
.
Los informes de cobertura también se generan si las pruebas fallan. Sin embargo, ten en cuenta que Esto no se extiende a las pruebas fallidas, solo se aprueban informes.
Cómo ver la cobertura
El informe de cobertura solo se genera en un formato no legible por humanos lcov
de un conjunto de datos
tengan un formato común. Desde esto, podemos usar la utilidad genhtml
(parte de lcov
proyecto) para generar un informe que se pueda ver en una
navegador:
genhtml --output genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"
Ten en cuenta que genhtml
también lee el código fuente para anotar que falta
cobertura en estos archivos. Para que esto funcione, se espera que
genhtml
se ejecuta en la raíz del proyecto de Bazel.
Para ver el resultado, simplemente abre el archivo index.html
generado en
genhtml
en cualquier navegador web.
Para obtener más información y ayuda sobre la herramienta genhtml
o
Formato de cobertura de lcov
; consulta el proyecto lcov.
Ejecución remota
La ejecución con la ejecución de prueba remota actualmente tiene algunas advertencias:
- La acción de combinación de informes todavía no se puede ejecutar de forma remota. Este es
ya que Bazel no considera los archivos de salida de cobertura como parte
en su gráfico (consulta este problema) y, por lo tanto, puede
no las tratan correctamente como entradas en la acción de combinación. Para
solucionar esto, usa
--strategy=CoverageReport=local
.- Nota: Tal vez sea necesario especificar
--strategy=CoverageReport=local,remote
en su lugar, si Bazel está configurado para probarlocal,remote
, debido a la forma en que Bazel resuelve las estrategias.
- Nota: Tal vez sea necesario especificar
- Tampoco se pueden usar
--remote_download_minimal
ni marcas similares. como consecuencia de lo primero. - Por el momento, Bazel no podrá crear información de cobertura si se realizan pruebas.
se almacenaron en caché anteriormente. Para solucionar esto,
--nocache_test_results
se puede configurar específicamente para ejecuciones de cobertura, aunque esto, por supuesto, genera un alto costo en términos de tiempos de prueba. --experimental_split_coverage_postprocessing
y--experimental_fetch_all_coverage_outputs
- Por lo general, la cobertura se realiza como parte de la acción de prueba. de forma predeterminada, no obtenemos toda la cobertura como salida del ejecución de forma predeterminada. Estas marcas anulan el valor predeterminado y obtienen los datos de cobertura. Consulta este problema para obtener más información más detalles.
Configuración de lenguaje específico
Java
Java debería funcionar de inmediato con la configuración predeterminada. El Las cadenas de herramientas de bazel contienen todo lo necesario para ejecución remota, incluida JUnit.
Python
Requisitos previos
La ejecución de cobertura con Python tiene algunos requisitos previos:
- Un objeto binario de Bazel que incluye b01c859 que debería ser cualquier versión de Bazel superior a 3.0.
- Una versión modificada de cover.py.
Cómo consumir la cover.py modificada
Una forma de hacerlo es mediante rules_python, que proporciona
la capacidad de usar un archivo requirements.txt
, los requisitos enumerados
del archivo se crean como destinos de Bazel con el
pip_install.
requirements.txt
debe tener la siguiente entrada:
git+https://github.com/ulfjack/coveragepy.git@lcov-support
Los archivos rules_python
, pip_install
y requirements.txt
deben usarse en el archivo WORKSPACE de la siguiente manera:
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",
)
Los objetivos de prueba pueden usar el requisito deCover.py
Configura lo siguiente en los archivos BUILD
:
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",
],
)
Si estás usando una cadena de herramientas hermética de Python, en lugar de agregar la cobertura
dependencia a cada objetivo de py_test
, puedes agregar la herramienta de cobertura a
la configuración de la cadena de herramientas.
Debido a que la regla pip_install depende de Python,
no se puede usar para recuperar el módulo coverage
.
En su lugar, agrega tu WORKSPACE
, p.ej.,
http_archive(
name = "coverage_linux_x86_64"",
build_file_content = """
py_library(
name = "coverage",
srcs = ["coverage/__main__.py"],
data = glob(["coverage/*", "coverage/**/*.py"]),
visibility = ["//visibility:public"],
)
""",
sha256 = "84631e81dd053e8a0d4967cedab6db94345f1c36107c71698f746cb2636c63e3",
type = "zip",
urls = [
"https://files.pythonhosted.org/packages/74/0d/0f3c522312fd27c32e1abe2fb5c323b583a5c108daf2c26d6e8dfdd5a105/coverage-6.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
],
)
Luego, configura tu cadena de herramientas de Python, p.ej.,
py_runtime(
name = "py3_runtime_linux_x86_64",
coverage_tool = "@coverage_linux_x86_64//:coverage",
files = ["@python3_9_x86_64-unknown-linux-gnu//:files"],
interpreter = "@python3_9_x86_64-unknown-linux-gnu//:bin/python3",
python_version = "PY3",
)
py_runtime_pair(
name = "python_runtimes_linux_x86_64",
py2_runtime = None,
py3_runtime = ":py3_runtime_linux_x86_64",
)
toolchain(
name = "python_toolchain_linux_x86_64",
exec_compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
toolchain = ":python_runtimes_linux_x86_64",
toolchain_type = "@bazel_tools//tools/python:toolchain_type",
)