使用 Bazel 編寫程式碼

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
  • --remote_download_minimal 及類似的旗標也不適用於前述結果。
  • 如果之前已快取測試,Bazel 目前無法建立涵蓋範圍資訊。為解決這個問題,您可以將 --nocache_test_results 設為涵蓋範圍,不過執行測試時可能會產生龐大費用。
  • --experimental_split_coverage_postprocessing--experimental_fetch_all_coverage_outputs
    • 測試期間通常會執行涵蓋率,因此根據預設,我們無法取得所有涵蓋率做為遠端執行作業的輸出內容。這些旗標會覆寫預設值,並取得涵蓋範圍資料。詳情請參閱這個問題

語言專屬設定

Java

Java 應該會立即支援預設設定。bazel 工具鍊內含遠端執行所需的一切資訊,包括 JUnit。

Python

事前準備

使用 Python 執行涵蓋範圍有一些必要條件:

採用修改過的涵蓋率.py

您可以透過 rules_python 達成這個目的,方法是使用 requirements.txt 檔案,接著使用 101}pip_install 存放區規則。

requirements.txt」應具備下列項目:

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

然後將 rules_pythonpip_installrequirements.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",
    ],
)