Bazel 具有 coverage
子指令,以在存放區中使用 bazel coverage
進行測試,產生程式碼涵蓋率報表。由於各種語言生態系統的慣用語,這些專案未必能正確運作。
本頁面說明建立及查看涵蓋率報表的一般程序,並會介紹一些設定通用的慣用語言注意事項。建議先閱讀一般區段,再熟悉特定語言的規定,以獲得最佳效能。另請參閱遠端執行部分,其中有其他注意事項。
雖然您可以自訂許多內容,但本文件著重於製作及使用 lcov
報表,這是目前最完整支援的路徑。
建立涵蓋範圍報表
準備工作
建立涵蓋範圍報表的基本工作流程需要下列項目:
- 有測試目標的基本存放區
- 安裝了語言專屬程式碼涵蓋率工具的工具鍊
- 正確的「檢測設備」設定
前兩個程式語言則多於語言,且較為複雜,但對複雜的專案較難。
這裡的「檢測」是指特定目標適用的涵蓋率工具。Bazel 可讓您使用 --instrumentation_filter
旗標,針對特定的檔案子集啟用此功能,而該標記會指定已透過檢測測試的目標。如要啟用檢測的檢測方法,則須使用 --instrument_test_targets
旗標。
根據預設,bazel 會嘗試比對目標套件,並將相關的篩選器列印為 INFO
訊息。
跑步涵蓋範圍
如要製作涵蓋範圍報表,請使用bazel coverage
--combined_report=lcov
[target]
。這項操作會對目標執行測試,產生每個檔案的 lcov 格式涵蓋率報表。
完成後,bazel 會執行一項動作,藉此收集所有產生的涵蓋檔案,並將這些檔案合併到一個檔案中,最後在 $(bazel info
output_path)/_coverage/_coverage_report.dat
下方建立。
測試失敗時,系統也會產生涵蓋範圍報表,但請注意,這不代表失敗的測試,只會回報通過的測試。
查看涵蓋範圍
涵蓋率報表只能以使用者可理解的 lcov
格式輸出。接著,我們會使用 genhtml
公用程式 (屬於 lcov 專案) 來產生可在網路瀏覽器中查看的報表:
genhtml --output genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"
請注意,genhtml
也會讀取原始碼,為這些檔案中缺少涵蓋範圍加上註解。為了達成這個目標,我們預期 genhtml
是在 bazel 專案的根目錄中執行。
如要查看結果,只要開啟任何網路瀏覽器,在 genhtml
目錄中產生的 index.html
檔案即可。
如需 genhtml
工具或 lcov
涵蓋範圍格式的其他協助與資訊,請參閱 lcov 專案。
遠端執行
執行遠端測試時,請注意以下幾點:
- 報表組合動作尚未從遠端執行。這是因為 Bazel 不會將涵蓋範圍輸出檔案視為其圖形的一部分 (請參閱這個問題),因此無法正確將其視為組合的輸入內容動作。如要解決這個問題,請使用
--strategy=CoverageReport=local
。- 注意:如果 Bazel 的設定方式為
local,remote
,由於 Bazel 必須解析策略,因此可能必須指定--strategy=CoverageReport=local,remote
。
- 注意:如果 Bazel 的設定方式為
--remote_download_minimal
及類似的旗標也不適用於前述結果。- 如果之前已快取測試,Bazel 目前無法建立涵蓋範圍資訊。為解決這個問題,您可以將
--nocache_test_results
設為涵蓋範圍,不過執行測試時可能會產生龐大費用。 --experimental_split_coverage_postprocessing
和--experimental_fetch_all_coverage_outputs
- 測試期間通常會執行涵蓋率,因此根據預設,我們無法取得所有涵蓋率做為遠端執行作業的輸出內容。這些旗標會覆寫預設值,並取得涵蓋範圍資料。詳情請參閱這個問題。
語言專屬設定
Java
Java 應該會立即支援預設設定。bazel 工具鍊內含遠端執行所需的一切資訊,包括 JUnit。
Python
事前準備
使用 Python 執行涵蓋範圍有一些必要條件:
- 內含 b01c859 的 bazel 二進位檔,任何 Bazel > 3.0。
- cover.py 的修改版本。
採用修改過的涵蓋率.py
您可以透過 rules_python 達成這個目的,方法是使用 requirements.txt
檔案,接著使用 101}pip_install 存放區規則。
「requirements.txt
」應具備下列項目:
git+https://github.com/ulfjack/coveragepy.git@lcov-support
然後將 rules_python
、pip_install
和 requirements.txt
檔案用於 WORKSPACE 檔案,如下所示:
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",
)
然後,您可以在 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",
],
)