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이 전략을 해결하는 방식 때문에 Bazel이
up to try
local,remote를 시도하도록 설정된 경우--strategy=CoverageReport=local,remote와 같은 항목을 지정해야 할 수 있습니다.
- 참고: Bazel이 전략을 해결하는 방식 때문에 Bazel이
up to try
--remote_download_minimal및 유사한 플래그도 이전 플래그의 결과로 사용할 수 없습니다.- 테스트
가 이전에 캐시된 경우 Bazel은 현재 적용 범위 정보를 만들지 못합니다. 이 문제를 해결하려면
--nocache_test_results적용 범위 실행에 대해 구체적으로 설정할 수 있지만 이렇게 하면 테스트 시간이 크게 늘어납니다. --experimental_split_coverage_postprocessing및--experimental_fetch_all_coverage_outputs- 일반적으로 적용 범위는 테스트 작업의 일부로 실행되므로 기본적으로 모든 적용 범위가 원격 실행의 출력으로 반환되지 않습니다. 이러한 플래그는 기본값을 재정의하고 적용 범위 데이터를 가져옵니다. 자세한 내용은 이 문제를 참고하세요.
언어별 구성
자바
Java는 기본 구성으로 즉시 사용할 수 있습니다. bazel 툴체인에는 JUnit을 비롯하여 원격 실행에 필요한 모든 항목이 포함되어 있습니다.
Python
기본 요건
Python으로 적용 범위를 실행하려면 몇 가지 기본 요건이 있습니다.
수정된 coverage.py 사용
이를 수행하는 한 가지 방법은 rules_python을 사용하는 것입니다. 이를 통해
requirements.txt 파일을 사용할 수 있으며 파일에 나열된 요구사항은
pip_install 저장소 규칙을 사용하여 bazel 대상으로 생성됩니다.
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",
)
그러면 테스트 대상에서 coverage.py 요구사항을
다음 파일에서 설정하여 사용할 수 있습니다.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",
],
)
기본 제공 Python 툴체인을 사용하는 경우 모든 py_test 대상에 적용 범위
종속 항목을 추가하는 대신
툴체인 구성에 적용 범위 도구를 추가할 수 있습니다.
pip_install 규칙은 Python
툴체인에 종속되므로 coverage 모듈을 가져오는 데 사용할 수 없습니다.
대신 WORKSPACE에 추가합니다(예:)
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",
],
)
그런 다음 Python 툴체인을 구성합니다(예:)
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",
)