Bazel có một lệnh phụ coverage để tạo báo cáo về mức độ sử dụng mã
trên các kho lưu trữ có thể kiểm thử bằng bazel coverage. Do đặc thù của các hệ sinh thái ngôn ngữ, nên việc thực hiện lệnh này cho một dự án nhất định không phải lúc nào cũng đơn giản.
Trang này ghi lại quy trình chung để tạo và xem báo cáo về mức độ sử dụng, đồng thời cũng có một số lưu ý cụ thể theo ngôn ngữ cho những ngôn ngữ có cấu hình đã được biết rõ. Bạn nên đọc phần chung trước, sau đó đọc về các yêu cầu đối với một ngôn ngữ cụ thể. Cũng hãy lưu ý phần thực thi từ xa , phần này yêu cầu một số điểm cần cân nhắc bổ sung.
Mặc dù bạn có thể tuỳ chỉnh nhiều, nhưng tài liệu này tập trung vào việc
tạo và sử dụng lcov báo cáo, đây hiện là
phương thức được hỗ trợ tốt nhất.
Tạo báo cáo về mức độ sử dụng
Chuẩn bị
Quy trình làm việc cơ bản để tạo báo cáo về mức độ sử dụng yêu cầu những điều sau:
- Một kho lưu trữ cơ bản có mục tiêu kiểm thử
- Một chuỗi công cụ đã cài đặt các công cụ về mức độ sử dụng mã theo ngôn ngữ
- Một cấu hình "instrumentation" chính xác
Hai điều đầu tiên là dành riêng cho ngôn ngữ và hầu hết đều đơn giản, tuy nhiên, điều thứ hai có thể khó hơn đối với các dự án phức tạp.
"Instrumentation" trong trường hợp này đề cập đến các công cụ về mức độ sử dụng được dùng cho một mục tiêu cụ thể. Bazel cho phép bật tính năng này cho một
nhóm nhỏ tệp cụ thể bằng cách sử dụng cờ
--instrumentation_filter, cờ này chỉ định một bộ lọc cho các mục tiêu được kiểm thử khi bật tính năng
instrumentation. Để bật tính năng instrumentation cho các bài kiểm thử, bạn cần có cờ
--instrument_test_targets.
Theo mặc định, bazel sẽ cố gắng khớp với(các) gói mục tiêu và in bộ lọc có liên quan dưới dạng thông báo INFO.
Chạy tính năng về mức độ sử dụng
Để tạo báo cáo về mức độ sử dụng, hãy dùng bazel coverage
--combined_report=lcov
[target]. Lệnh này sẽ chạy các bài kiểm thử cho mục tiêu, tạo báo cáo về mức độ sử dụng ở định dạng lcov cho từng tệp.
Sau khi hoàn tất, bazel sẽ chạy một hành động thu thập tất cả các tệp về mức độ sử dụng đã tạo
và hợp nhất các tệp đó thành một tệp. Tệp này sẽ được tạo trong $(bazel info
output_path)/_coverage/_coverage_report.dat.
Báo cáo về mức độ sử dụng cũng được tạo nếu các bài kiểm thử không thành công, mặc dù xin lưu ý rằng báo cáo này không bao gồm các bài kiểm thử không thành công – chỉ những bài kiểm thử thành công mới được báo cáo.
Xem báo cáo về mức độ sử dụng
Báo cáo về mức độ sử dụng chỉ được xuất ở định dạng lcov không thể đọc được. Từ đó, chúng ta có thể sử dụng tiện ích genhtml (một phần của dự án lcov) để tạo báo cáo có thể xem được trong trình duyệt web:
genhtml --output genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"
Xin lưu ý rằng genhtml cũng đọc mã nguồn để chú thích mức độ sử dụng còn thiếu trong các tệp này. Để tính năng này hoạt động, bạn cần thực thi genhtml trong thư mục gốc của dự án bazel.
Để xem kết quả, bạn chỉ cần mở tệp index.html được tạo trong thư mục genhtml ở bất kỳ trình duyệt web nào.
Để được trợ giúp thêm và biết thêm thông tin về công cụ genhtml hoặc định dạng về mức độ sử dụng
lcov , hãy xem dự án lcov.
Thực thi từ xa
Việc chạy với tính năng thực thi kiểm thử từ xa hiện có một số lưu ý:
- Hành động kết hợp báo cáo chưa thể chạy từ xa. Điều này là
do Bazel không coi các tệp đầu ra về mức độ sử dụng là một phần của
biểu đồ (xem vấn đề này) và do đó
không thể xử lý chính xác các tệp đó làm dữ liệu đầu vào cho hành động kết hợp. Để khắc phục vấn đề này, hãy sử dụng
--strategy=CoverageReport=local.- Lưu ý: Bạn có thể cần chỉ định một nội dung như
--strategy=CoverageReport=local,remotethay vìlocal,remotenếu Bazel được thiết lập để thửlocal,remote, do cách Bazel phân giải các chiến lược.
- Lưu ý: Bạn có thể cần chỉ định một nội dung như
- Bạn cũng không thể sử dụng
--remote_download_minimalvà các cờ tương tự do hậu quả của cờ trước đó. - Bazel hiện sẽ không tạo được thông tin về mức độ sử dụng nếu các bài kiểm thử đã được lưu vào bộ nhớ đệm trước đó. Để khắc phục vấn đề này, bạn có thể đặt
--nocache_test_resultsdành riêng cho các lần chạy về mức độ sử dụng, mặc dù điều này chắc chắn sẽ gây tốn kém nhiều về thời gian kiểm thử. --experimental_split_coverage_postprocessingvà--experimental_fetch_all_coverage_outputs- Thông thường, mức độ sử dụng được chạy như một phần của hành động kiểm thử. Vì vậy, theo mặc định, chúng ta không nhận được tất cả mức độ sử dụng dưới dạng đầu ra của quá trình thực thi từ xa. Các cờ này sẽ ghi đè giá trị mặc định và thu thập dữ liệu về mức độ sử dụng. Hãy xem vấn đề này để biết thêm chi tiết.
Cấu hình theo ngôn ngữ cụ thể
Java
Java sẽ hoạt động ngay khi bạn sử dụng cấu hình mặc định. Các chuỗi công cụ bazel cũng chứa mọi thứ cần thiết để thực thi từ xa, bao gồm cả JUnit.
Python
Điều kiện tiên quyết
Việc chạy tính năng về mức độ sử dụng bằng python có một số điều kiện tiên quyết:
- Một tệp nhị phân bazel bao gồm b01c859, phải là bất kỳ Bazel > 3.0 nào.
- Một phiên bản đã sửa đổi của coverage.py.
Sử dụng coverage.py đã sửa đổi
Một cách để thực hiện việc này là thông qua rules_python. Cách này cho phép bạn sử dụng tệp requirements.txt. Các yêu cầu được liệt kê trong tệp sẽ được tạo dưới dạng mục tiêu bazel bằng quy tắc kho lưu trữ pip_install.
requirements.txt phải có mục sau:
git+https://github.com/ulfjack/coveragepy.git@lcov-support
Sau đó, bạn nên sử dụng tệp rules_python, pip_install và requirements.txt trong tệp WORKSPACE như sau:
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",
)
Sau đó, các mục tiêu kiểm thử có thể sử dụng yêu cầu coverage.py bằng cách đặt nội dung sau trong tệp 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",
],
)
Nếu đang sử dụng chuỗi công cụ Python khép kín, thay vì thêm phần phụ thuộc về mức độ sử dụng vào mọi mục tiêu py_test, bạn có thể thêm công cụ về mức độ sử dụng vào cấu hình chuỗi công cụ.
Vì quy tắc pip_install phụ thuộc vào chuỗi công cụ Python, nên bạn không thể dùng quy tắc này để tìm nạp mô-đun coverage.
Thay vào đó, hãy thêm vào WORKSPACE, ví dụ:
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",
],
)
Sau đó, hãy định cấu hình chuỗi công cụ python, ví dụ:
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",
)