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

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 प्रोजेक्ट के रूट में एक्ज़ीक्यूट किया जाए.

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

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

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

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

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