Cakupan kode dengan Bazel

Laporkan masalah Lihat sumber Per Malam · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Bazel memiliki sub-perintah coverage untuk menghasilkan cakupan kode melaporkan repositori yang dapat diuji dengan bazel coverage. Tenggat pada keistimewaan berbagai ekosistem bahasa, hal itu tidak selalu sepele agar proses ini berhasil untuk proyek tertentu.

Halaman ini mendokumentasikan proses umum untuk membuat dan menampilkan laporan cakupan, serta menampilkan beberapa catatan khusus bahasa untuk bahasa yang konfigurasinya dikenal luas. Sebaiknya dibaca terlebih dahulu membaca bagian umum, lalu membaca tentang persyaratan untuk bahasa tertentu. Perhatikan juga bagian eksekusi jarak jauh, yang memerlukan pertimbangan tambahan.

Meskipun banyak penyesuaian dapat dilakukan, dokumen ini berfokus pada untuk membuat dan menggunakan laporan lcov, yang saat ini merupakan rute yang paling didukung.

Membuat laporan cakupan

Persiapan

Alur kerja dasar untuk membuat laporan cakupan memerlukan berikut ini:

  • Repositori dasar dengan target pengujian
  • Toolchain dengan alat cakupan kode khusus bahasa terinstal
  • "Instrumentasi" yang tepat konfigurasi

Dua yang sebelumnya spesifik per bahasa dan sebagian besar bersifat lugas, namun yang terakhir bisa lebih sulit untuk proyek yang kompleks.

"Instrumentasi" dalam hal ini mengacu pada alat cakupan yang yang digunakan untuk target tertentu. Bazel mengizinkan pengaktifan ini untuk {i>subset<i} tertentu dari file menggunakan --instrumentation_filter , yang menentukan filter untuk target yang diuji dengan instrumentasi diaktifkan. Untuk mengaktifkan instrumentasi pengujian, metode --instrument_test_targets diperlukan.

Secara default, bazel akan mencoba mencocokkan paket target, lalu mencetak filter yang relevan sebagai pesan INFO.

Cakupan lari

Untuk membuat laporan cakupan, gunakan bazel coverage --combined_report=lcov [target]. Fungsi ini menjalankan pengujian untuk target, yang menghasilkan laporan cakupan dalam format lcov untuk setiap file.

Setelah selesai, bazel menjalankan tindakan yang mengumpulkan semua file cakupan, dan menggabungkannya menjadi satu, yang akhirnya dibuat di $(bazel info output_path)/_coverage/_coverage_report.dat.

Laporan cakupan juga dibuat jika pengujian gagal, tetapi perhatikan bahwa ini tidak mencakup pengujian yang gagal - hanya pengujian yang lulus yang dilaporkan.

Melihat liputan

Laporan cakupan hanya dihasilkan dalam bahasa lcov yang tidak dapat dibaca manusia format font. Dari sini, kita dapat menggunakan utilitas genhtml (bagian dari layar project) untuk menghasilkan laporan yang dapat dilihat di web browser:

genhtml --output genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"

Perhatikan bahwa genhtml juga membaca kode sumber untuk memberi anotasi yang hilang cakupan dalam file ini. Agar dapat berjalan, diharapkan genhtml dieksekusi di root project bazel.

Untuk melihat hasilnya, cukup buka file index.html yang dihasilkan di genhtml di browser web apa pun.

Untuk bantuan dan informasi lebih lanjut tentang alat genhtml, atau Format cakupan lcov, lihat project lcov.

Eksekusi jarak jauh

Menjalankan dengan eksekusi uji jarak jauh saat ini memiliki beberapa peringatan:

  • Tindakan kombinasi laporan belum dapat dijalankan dari jarak jauh. Ini adalah karena Bazel tidak menganggap file {i>output<i} cakupan sebagai bagian dari grafiknya (lihat masalah ini), dan karenanya dapat tidak memperlakukannya dengan benar sebagai {i>input<i} untuk tindakan kombinasi. Kepada mengatasi masalah ini, gunakan --strategy=CoverageReport=local.
    • Catatan: Mungkin perlu menentukan sesuatu seperti --strategy=CoverageReport=local,remote saja, jika Bazel disetel hingga mencoba local,remote, karena cara Bazel menyelesaikan strategi.
  • --remote_download_minimal dan tanda serupa juga tidak dapat digunakan sebagai konsekuensi dari yang pertama.
  • Bazel saat ini akan gagal membuat informasi cakupan jika pengujian telah disimpan di cache sebelumnya. Untuk mengatasi hal ini, --nocache_test_results dapat disetel khusus untuk operasi 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 {i>output<i} dari remote secara {i>default<i}. Tanda ini mengganti tanda {i>default<i} dan memperoleh data cakupan. Lihat masalah ini untuk informasi selengkapnya spesifikasi pendukung.

Konfigurasi khusus bahasa

Java

Java harus berfungsi secara langsung dengan konfigurasi default. Tujuan rantai alat bazel berisi semua hal yang diperlukan untuk eksekusi jarak jauh, termasuk JUnit.

Python

Prasyarat

Menjalankan cakupan dengan python memiliki beberapa prasyarat:

Memakai cakupan.py yang dimodifikasi

Cara untuk melakukannya adalah melalui rules_python, yang memberikan kemampuan untuk menggunakan file requirements.txt, persyaratan yang tercantum dalam file akan dibuat sebagai target bazel menggunakan aturan repositori pip_install.

requirements.txt harus memiliki entri berikut:

git+https://github.com/ulfjack/coveragepy.git@lcov-support

Kemudian, file rules_python, pip_install, dan requirements.txt harus digunakan di 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 cakupan.py kemudian dapat digunakan oleh target pengujian oleh menetapkan setelan 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 Anda menggunakan toolchain Python hermetic, sebagai ganti menambahkan cakupan dependensi ke setiap target py_test, Anda dapat menambahkan alat cakupan ke untuk konfigurasi toolchain.

Karena aturan pip_install bergantung pada Python toolchain, alat ini tidak dapat digunakan untuk mengambil modul coverage. Sebagai gantinya, tambahkan WORKSPACE Anda, mis.

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 sebagai 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",
)