बेज़ेल के साथ कोड कवरेज

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 --branch-coverage --output genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"

ध्यान दें कि genhtml, सोर्स कोड भी पढ़ता है, ताकि इन फ़ाइलों में कवरेज की कमी के बारे में जानकारी दी जा सके. इसके लिए, यह ज़रूरी है कि genhtml को bazel प्रोजेक्ट के रूट में एक्ज़ीक्यूट किया जाए.

नतीजा देखने के लिए, किसी भी वेब ब्राउज़र में genhtml डायरेक्ट्री में जनरेट हुई index.html फ़ाइल खोलें.

genhtml टूल या lcov कवरेज फ़ॉर्मैट के बारे में ज़्यादा मदद और जानकारी पाने के लिए, lcov प्रोजेक्ट देखें.

रिमोट एक्ज़ीक्यूशन

रिमोट टेस्ट एक्ज़ीक्यूशन के साथ काम करने में कुछ समस्याएं आ सकती हैं:

  • रिपोर्ट को एक साथ लाने की कार्रवाई, फ़िलहाल रिमोट तरीके से नहीं की जा सकती. ऐसा इसलिए है क्योंकि Bazel, कवरेज आउटपुट फ़ाइलों को अपने ग्राफ़ का हिस्सा नहीं मानता (Bazel की समस्या #4685). इसलिए, वह उन्हें एक साथ लाने की कार्रवाई के लिए, इनपुट के तौर पर सही तरीके से इस्तेमाल नहीं कर सकता. इससे बचने के लिए, --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
    • आम तौर पर, कवरेज को टेस्ट ऐक्शन के हिस्से के तौर पर चलाया जाता है. इसलिए, डिफ़ॉल्ट रूप से, हमें रिमोट एक्ज़ीक्यूशन के आउटपुट के तौर पर, कवरेज का पूरा डेटा नहीं मिलता. ये फ़्लैग, डिफ़ॉल्ट सेटिंग को बदल देते हैं और कवरेज का डेटा हासिल करते हैं. ज़्यादा जानकारी के लिए, Bazel की समस्या #4685 देखें.

भाषा के हिसाब से कॉन्फ़िगरेशन

यहां दिए गए सेक्शन में, Bazel के साथ कोड कवरेज सेट अप करने के लिए, भाषा के हिसाब से ज़रूरी बातों के बारे में बताया गया है.

C++

Linux

C++ कवरेज, डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ बिना किसी समस्या के काम करना चाहिए.

macOS

GCOV_PREFIX_STRIP की डिफ़ॉल्ट वैल्यू, लगभग हमेशा गलत होती है. इसलिए, इसे मैन्युअल तरीके से अडजस्ट करना ज़रूरी है, क्योंकि सही वैल्यू आपके सेटअप पर निर्भर करती है.

वैल्यू गलत होने पर, कवरेज का कोई डेटा नहीं मिलेगा.

GCOV_PREFIX_STRIP=10 bazel coverage //foo:foo_test --test_env=GCOV_PREFIX_STRIP=10` सेट करने का उदाहरण

Java

Java, डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ बिना किसी समस्या के काम करना चाहिए. bazel टूलचेन में, रिमोट एक्ज़ीक्यूशन के लिए ज़रूरी सभी चीज़ें शामिल होती हैं. इनमें JUnit भी शामिल है.

Python

Python में कवरेज की सुविधा चालू करने के लिए ज़रूरी अतिरिक्त चरणों के बारे में जानने के लिए, rules_python कवरेज के दस्तावेज़ देखें.