Bazel memiliki sub-perintah coverage
untuk menghasilkan laporan cakupan
kode di repositori yang dapat diuji dengan bazel coverage
. Karena
keunikan berbagai ekosistem bahasa, tidak
selalu mudah untuk membuat hal ini berfungsi untuk project tertentu.
Halaman ini mendokumentasikan proses umum untuk membuat dan melihat laporan cakupan, serta menampilkan beberapa catatan khusus bahasa untuk bahasa yang konfigurasinya sudah dikenal. Sebaiknya baca terlebih dahulu bagian umum, lalu baca persyaratan untuk bahasa tertentu. Perhatikan juga bagian eksekusi jarak jauh, yang memerlukan beberapa pertimbangan tambahan.
Meskipun banyak penyesuaian yang dapat dilakukan, dokumen ini berfokus pada
membuat dan menggunakan laporan lcov
, yang saat ini merupakan
jalur yang paling didukung.
Membuat laporan cakupan
Persiapan
Alur kerja dasar untuk membuat laporan cakupan memerlukan hal berikut:
- Repositori dasar dengan target pengujian
- Toolchain dengan alat cakupan kode khusus bahasa yang diinstal
- Konfigurasi "instrumentasi" yang benar
Dua yang pertama bersifat spesifik per bahasa dan sebagian besar mudah, tetapi yang terakhir dapat lebih sulit untuk project yang kompleks.
Dalam hal ini, "Instrumentasi" mengacu pada alat cakupan yang
digunakan untuk target tertentu. Bazel memungkinkan pengaktifan ini untuk
subkumpulan file tertentu menggunakan
tanda --instrumentation_filter
, yang menentukan filter untuk target yang diuji dengan
instrumentasi yang diaktifkan. Untuk mengaktifkan instrumentasi untuk pengujian, tanda
--instrument_test_targets
diperlukan.
Secara default, bazel mencoba mencocokkan paket target, dan mencetak
filter yang relevan sebagai pesan INFO
.
Menjalankan cakupan
Untuk membuat laporan cakupan, gunakan bazel coverage
--combined_report=lcov
[target]
. Tindakan ini akan menjalankan
pengujian untuk target, menghasilkan laporan cakupan dalam format lcov
untuk setiap file.
Setelah selesai, bazel akan menjalankan tindakan yang mengumpulkan semua file cakupan
yang dihasilkan, dan menggabungkannya menjadi satu, yang kemudian
dibuat di bagian $(bazel info
output_path)/_coverage/_coverage_report.dat
.
Laporan cakupan juga dihasilkan jika pengujian gagal, meskipun perlu diperhatikan bahwa hal ini tidak berlaku untuk pengujian yang gagal - hanya pengujian yang lulus yang dilaporkan.
Melihat cakupan
Laporan cakupan hanya menghasilkan output dalam format lcov
yang tidak dapat dibaca manusia. Dari sini, kita dapat menggunakan utilitas genhtml
(bagian dari project
lcov) untuk membuat laporan yang dapat dilihat di browser
web:
genhtml --output genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"
Perhatikan bahwa genhtml
juga membaca kode sumber, untuk menganotasi cakupan
yang hilang dalam file ini. Agar berfungsi, genhtml
diharapkan dijalankan di root project bazel.
Untuk melihat hasilnya, cukup buka file index.html
yang dihasilkan di
direktori genhtml
di browser web mana pun.
Untuk bantuan dan informasi lebih lanjut tentang alat genhtml
, atau
format cakupan lcov
, lihat project lcov.
Eksekusi jarak jauh
Menjalankan dengan eksekusi pengujian jarak jauh saat ini memiliki beberapa batasan:
- Tindakan kombinasi laporan belum dapat dijalankan dari jarak jauh. Hal ini
karena Bazel tidak menganggap file output cakupan sebagai bagian dari
grafiknya (lihat masalah ini), sehingga tidak dapat
memperlakukannya dengan benar sebagai input untuk tindakan kombinasi. Untuk
mengatasi hal ini, gunakan
--strategy=CoverageReport=local
.- Catatan: Anda mungkin perlu menentukan sesuatu seperti
--strategy=CoverageReport=local,remote
, jika Bazel disiapkan untuk mencobalocal,remote
, karena cara Bazel me-resolve strategi.
- Catatan: Anda mungkin perlu menentukan sesuatu seperti
--remote_download_minimal
dan flag serupa juga tidak dapat digunakan sebagai konsekuensi dari flag sebelumnya.- Bazel saat ini akan gagal membuat informasi cakupan jika pengujian
telah di-cache sebelumnya. Untuk mengatasi hal ini,
--nocache_test_results
dapat ditetapkan secara khusus untuk menjalankan cakupan, meskipun hal ini tentu saja menimbulkan biaya yang besar dalam hal waktu pengujian. --experimental_split_coverage_postprocessing
dan--experimental_fetch_all_coverage_outputs
- Biasanya cakupan dijalankan sebagai bagian dari tindakan pengujian, sehingga secara default, kita tidak mendapatkan semua cakupan kembali sebagai output dari eksekusi jarak jauh secara default. Flag ini mengganti default dan mendapatkan data cakupan. Lihat masalah ini untuk mengetahui detail selengkapnya.
Konfigurasi khusus bahasa
Java
Java akan berfungsi secara otomatis dengan konfigurasi default. Toolchain bazel juga berisi semua yang diperlukan untuk eksekusi jarak jauh, termasuk JUnit.
Python
Prasyarat
Menjalankan cakupan dengan python memiliki beberapa prasyarat:
- Biner bazel yang menyertakan b01c859, yang harus berupa Bazel >3.0.
- Versi coverage.py yang dimodifikasi.
Menggunakan coverage.py yang diubah
Cara melakukannya adalah melalui rules_python, yang memberikan
kemampuan untuk menggunakan file requirements.txt
, persyaratan yang tercantum
dalam file kemudian dibuat sebagai target bazel menggunakan
aturan repositori pip_install.
requirements.txt
harus memiliki entri berikut:
git+https://github.com/ulfjack/coveragepy.git@lcov-support
File rules_python
, pip_install
, dan requirements.txt
kemudian harus digunakan dalam file WORKSPACE sebagai:
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",
)
Persyaratan coverage.py kemudian dapat digunakan oleh target pengujian dengan
menetapkan hal berikut dalam file 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",
],
)
Jika menggunakan toolchain Python hermetis, Anda dapat menambahkan alat cakupan ke
konfigurasi toolchain, bukan menambahkan dependensi cakupan
ke setiap target py_test
.
Karena aturan pip_install bergantung pada toolchain
Python, aturan ini tidak dapat digunakan untuk mengambil modul coverage
.
Sebagai gantinya, tambahkan WORKSPACE
Anda, misalnya
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",
],
)
Kemudian, konfigurasikan toolchain python Anda seperti misalnya
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",
)