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

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 की रणनीतियों को हल करने के तरीके की वजह से, अगर 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 कवरेज के दस्तावेज़ देखें.