Bazel में coverage
सब-कमांड होता है, जिसकी मदद से उन रिपॉज़िटरी के लिए कोड कवरेज की रिपोर्ट जनरेट की जा सकती हैं जिनकी जांच bazel coverage
से की जा सकती है. अलग-अलग भाषा के सिस्टम के हिसाब से, किसी प्रोजेक्ट के लिए इसे इस्तेमाल करना हमेशा आसान नहीं होता.
इस पेज पर, कवरेज रिपोर्ट बनाने और देखने की सामान्य प्रोसेस के बारे में बताया गया है. साथ ही, उन भाषाओं के लिए कुछ खास नोट भी दिए गए हैं जिनका कॉन्फ़िगरेशन अच्छी तरह से जाना जाता है. इसे सबसे पहले सामान्य सेक्शन और फिर किसी खास भाषा की ज़रूरी शर्तों के बारे में पढ़कर पढ़ा जा सकता है. रिमोट तौर पर लागू करने वाले सेक्शन पर भी ध्यान दें. इसके लिए, कुछ और बातों का ध्यान रखना ज़रूरी है.
इस दस्तावेज़ में, lcov
रिपोर्ट बनाने और उनका इस्तेमाल करने पर फ़ोकस किया गया है. फ़िलहाल, यह सबसे सही तरीका है. हालांकि, इसमें ज़रूरत के हिसाब से कई बदलाव किए जा सकते हैं.
कवरेज रिपोर्ट बनाना
वीडियो की रणनीति
कवरेज रिपोर्ट बनाने के लिए बुनियादी वर्कफ़्लो के लिए ये ज़रूरी हैं:
- टेस्ट टारगेट के साथ बुनियादी डेटा स्टोर करने की जगह
- भाषा के हिसाब से कोड कवरेज टूल इंस्टॉल करने वाला टूलचेन
- एक सही "इंस्ट्रुमेंटेशन" कॉन्फ़िगरेशन
पहले वाले दो तरीके, खास तौर पर भाषा के हिसाब से हैं और ज़्यादातर आसान हैं. हालांकि, बाद वाले प्रोजेक्ट जटिल प्रोजेक्ट के लिए ज़्यादा मुश्किल हो सकते हैं.
इस मामले में, "इंस्ट्रूमेंटेशन" का मतलब उन कवरेज टूल से है जिनका इस्तेमाल किसी खास टारगेट के लिए किया जाता है. Baze, --instrumentation_filter
फ़्लैग का इस्तेमाल करके फ़ाइलों के एक खास सबसेट के लिए इसे चालू करने की अनुमति देता है.
इससे, उन टारगेट के लिए एक फ़िल्टर तय होता है जिनकी जांच
इंस्ट्रूमेंटेशन के साथ की जाती है. टेस्ट के लिए इंस्ट्रुमेंटेशन चालू करने के लिए, --instrument_test_targets
फ़्लैग ज़रूरी है.
डिफ़ॉल्ट रूप से, basel टारगेट पैकेज को मैच करने की कोशिश करता है और ज़रूरत के हिसाब से बने फ़िल्टर को INFO
मैसेज के तौर पर प्रिंट करता है.
रनिंग कवरेज
कवरेज रिपोर्ट बनाने के लिए, bazel coverage
--combined_report=lcov
[target]
का इस्तेमाल करें. यह टारगेट के लिए जांच करता है और हर फ़ाइल के लिए lcov फ़ॉर्मैट में कवरेज रिपोर्ट जनरेट करता है.
काम पूरा हो जाने के बाद, बैजल एक ऐसी कार्रवाई करता है जो बनाई गई सभी कवरेज फ़ाइलें इकट्ठा करके, उन्हें एक फ़ाइल में मर्ज कर देती है, जो आखिर में $(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
आज़माने के लिए सेट अप किया गया है, तो हो सकता है कि इसके बजाय--strategy=CoverageReport=local,remote
जैसा कुछ बताना ज़रूरी हो. ऐसा इसलिए, क्योंकि Bazel रणनीतियों को हल करने का तरीका अपनाता है.
- ध्यान दें: अगर Bazel को
--remote_download_minimal
और मिलते-जुलते फ़्लैग का इस्तेमाल भी नहीं किया जा सकता.- अगर टेस्ट पहले से कैश मेमोरी में सेव किए गए हैं, तो फ़िलहाल Basel, कवरेज की जानकारी नहीं बना पाएगा. इससे बचने के लिए,
--nocache_test_results
को खास तौर पर, कवरेज चलाने के लिए सेट किया जा सकता है. हालांकि, जांच में लगने वाले समय के हिसाब से, इस सुविधा के लिए आपको भारी शुल्क देना पड़ता है. --experimental_split_coverage_postprocessing
और--experimental_fetch_all_coverage_outputs
- आम तौर पर, कवरेज को टेस्ट ऐक्शन के हिस्से के तौर पर चलाया जाता है. इसलिए, डिफ़ॉल्ट रूप से, हमें रिमोट रन के आउटपुट के तौर पर सारा कवरेज वापस नहीं मिलता. ये फ़्लैग, डिफ़ॉल्ट सेटिंग को बदल देते हैं और कवरेज का डेटा हासिल करते हैं. ज़्यादा जानकारी के लिए, यह समस्या देखें.
भाषा के हिसाब से कॉन्फ़िगरेशन
Java
Java, डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ बिना किसी समस्या के काम करना चाहिए. bazel टूलचेन में, रिमोट तौर पर प्रोग्राम चलाने के लिए ज़रूरी सभी चीज़ें मौजूद होती हैं. इनमें JUnit भी शामिल है.
Python
ज़रूरी शर्तें
Python के साथ कवरेज चलाना, कुछ ज़रूरी शर्तें हैं:
- Bazel बाइनरी, जिसमें b01c859 शामिल हो. यह बाइनरी, Bazel >3.0 होनी चाहिए.
- 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",
)
इसके बाद, BUILD
फ़ाइलों में यह सेटिंग सेट करके, कवरेज.py की ज़रूरी शर्त का इस्तेमाल जांच के लक्ष्यों के लिए किया जा सकता है:
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
toolchain पर निर्भर करता है. इसलिए, इसका इस्तेमाल 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",
)