कोड कवरेज के चार सामान्य टाइप

कोड कवरेज के बारे में जानें और उसे मेज़र करने के चार सामान्य तरीके खोजें.

क्या आपने "कोड कवरेज" वाक्यांश सुना है? इस पोस्ट में, हम जानेंगे कि टेस्ट में कोड कवरेज क्या है और उसे मेज़र करने के चार सामान्य तरीके क्या हैं.

कोड कवरेज क्या होता है?

कोड कवरेज एक ऐसी मेट्रिक है जिससे पता चलता है कि आपकी जांच में कितना सोर्स कोड का इस्तेमाल हुआ है. इससे, उन जगहों का पता लगाने में मदद मिलती है जिनकी ठीक से जांच नहीं की जा सकती.

अक्सर, इन मेट्रिक को इस तरह रिकॉर्ड किया जाता है:

फ़ाइल % स्टेटमेंट % ब्रांच % फ़ंक्शन % लाइनें शामिल नहीं की गई लाइनें
file.js 90% 100% 90% 80% 89,256
coffee.js 55.55% 80% 50% 62.5% 10 से 11, 18

नई सुविधाएं और टेस्ट जोड़ने पर, कोड कवरेज का प्रतिशत बढ़ने से आपको इस बात पर भरोसा हो सकता है कि आपके ऐप्लिकेशन की जांच पूरी हो गई है. हालांकि, आपको इस बारे में और भी जानकारी मिल सकती है.

कोड कवरेज के चार सामान्य टाइप

कोड कवरेज इकट्ठा करने और उसका हिसाब लगाने के चार सामान्य तरीके हैं: फ़ंक्शन, लाइन, ब्रांच, और स्टेटमेंट कवरेज.

चार तरह के टेक्स्ट कवरेज.

यह देखने के लिए कि हर तरह का कोड कवरेज उसके प्रतिशत का हिसाब कैसे लगाता है, कॉफ़ी सामग्री का हिसाब लगाने के लिए, नीचे दिए गए उदाहरण के तौर पर देखें:

/* coffee.js */

export function calcCoffeeIngredient(coffeeName, cup = 1) {
  let espresso, water;

  if (coffeeName === 'espresso') {
    espresso = 30 * cup;
    return { espresso };
  }

  if (coffeeName === 'americano') {
    espresso = 30 * cup; water = 70 * cup;
    return { espresso, water };
  }

  return {};
}

export function isValidCoffee(name) {
  return ['espresso', 'americano', 'mocha'].includes(name);
}

calcCoffeeIngredient फ़ंक्शन की पुष्टि करने वाले टेस्ट ये हैं:

/* coffee.test.js */

import { describe, expect, assert, it } from 'vitest';
import { calcCoffeeIngredient } from '../src/coffee-incomplete';

describe('Coffee', () => {
  it('should have espresso', () => {
    const result = calcCoffeeIngredient('espresso', 2);
    expect(result).to.deep.equal({ espresso: 60 });
  });

  it('should have nothing', () => {
    const result = calcCoffeeIngredient('unknown');
    expect(result).to.deep.equal({});
  });
});

कोड चलाने और उसकी जांच करने के लिए, इस लाइव डेमो पर जाएं या डेटा स्टोर करने की जगह पर जाएं.

फ़ंक्शन कवरेज

कोड कवरेज: 50%

/* coffee.js */

export function calcCoffeeIngredient(coffeeName, cup = 1) {
  // ...
}

function isValidCoffee(name) {
  // ...
}

फ़ंक्शन कवरेज एक आसान मेट्रिक है. यह आपके कोड में मौजूद उन फ़ंक्शन का प्रतिशत कैप्चर करता है जिन्हें टेस्ट के ज़रिए कॉल किया जाता है.

कोड उदाहरण में दो फ़ंक्शन हैं: calcCoffeeIngredient और isValidCoffee. टेस्ट में सिर्फ़ calcCoffeeIngredient फ़ंक्शन को कॉल किया जाता है. इसलिए, फ़ंक्शन का कवरेज 50% है.

लाइन कवरेज

कोड कवरेज: 62.5%

/* coffee.js */

export function calcCoffeeIngredient(coffeeName, cup = 1) {
  let espresso, water;

  if (coffeeName === 'espresso') {
    espresso = 30 * cup;
    return { espresso };
  }

  if (coffeeName === 'americano') {
    espresso = 30 * cup; water = 70 * cup;
    return { espresso, water };
  }

  return {};
}

export function isValidCoffee(name) {
  return ['espresso', 'americano', 'mocha'].includes(name);
}

लाइन कवरेज, उन एक्ज़ीक्यूटेबल कोड लाइनों के प्रतिशत का आकलन करता है जिन्हें आपके टेस्ट सुइट ने लागू किया है. अगर कोड की किसी लाइन पर कोई कार्रवाई नहीं हुई है, तो इसका मतलब है कि कोड के कुछ हिस्से की जांच नहीं हुई है.

कोड के उदाहरण में एक्ज़ीक्यूटेबल कोड (लाल और हरे रंग से हाइलाइट किया गया) की आठ लाइनें हैं, लेकिन टेस्ट में americano शर्त (दो लाइनें) और isValidCoffee फ़ंक्शन (एक लाइन) को एक्ज़ीक्यूट नहीं किया जाता. इससे 62.5% का लाइन कवरेज होता है.

ध्यान दें कि लाइन कवरेज में, function isValidCoffee(name) और let espresso, water; जैसे एलान वाले स्टेटमेंट शामिल नहीं होते, क्योंकि इन्हें एक्ज़ीक्यूट नहीं किया जा सकता.

शाखा कवरेज

कोड कवरेज: 80%

/* coffee.js */

export function calcCoffeeIngredient(coffeeName, cup = 1) {
  // ...

  if (coffeeName === 'espresso') {
    // ...
    return { espresso };
  }

  if (coffeeName === 'americano') {
    // ...
    return { espresso, water };
  }

  return {};
}
…

शाखा कवरेज, कोड में हस्ताक्षर की गई शाखाओं या डिसिज़न पॉइंट के प्रतिशत का आकलन करता है, जैसे कि स्टेटमेंट या लूप. यह तय करता है कि टेस्ट, कंडिशनल स्टेटमेंट की सही और गलत, दोनों ब्रांच की जांच करते हैं या नहीं.

कोड उदाहरण में पांच ब्रांच हैं:

  1. सिर्फ़ coffeeName चेक का निशान. की मदद से calcCoffeeIngredient को कॉल किया जा रहा है
  2. coffeeName और cup चेक का निशान. के साथ calcCoffeeIngredient को कॉल किया जा रहा है
  3. कॉफ़ी एस्प्रेसो चेक का निशान. है
  4. कॉफ़ी अमेरिकानो X का निशान. है
  5. दूसरी कॉफ़ी चेक का निशान.

जांच में Coffee is Americano शर्त को छोड़कर, सभी ब्रांच को शामिल किया गया है. इसलिए, ब्रांच का कवरेज 80% है.

स्टेटमेंट कवरेज

कोड कवरेज: 55.55%

/* coffee.js */

export function calcCoffeeIngredient(coffeeName, cup = 1) {
  let espresso, water;

  if (coffeeName === 'espresso') {
    espresso = 30 * cup;
    return { espresso };
  }

  if (coffeeName === 'americano') {
    espresso = 30 * cup; water = 70 * cup;
    return { espresso, water };
  }

  return {};
}

export function isValidCoffee(name) {
  return ['espresso', 'americano', 'mocha'].includes(name);
}

स्टेटमेंट कवरेज आपके कोड में मौजूद उन स्टेटमेंट के प्रतिशत को मेज़र करता है जिन्हें आपके टेस्ट ने एक्ज़ीक्यूट किया है. पहली नज़र में आपको लग सकता है, “क्या यह लाइन कवरेज जैसा नहीं है?” स्टेटमेंट कवरेज, लाइन कवरेज की तरह ही होता है. हालांकि, यह कोड की एक लाइन में मौजूद उन सभी स्टेटमेंट को ध्यान में रखता है जिनमें कई स्टेटमेंट होते हैं.

कोड उदाहरण में, एक्ज़ीक्यूटेबल कोड की आठ लाइनें हैं, लेकिन उसमें नौ स्टेटमेंट हैं. क्या आप दो स्टेटमेंट वाली लाइन देख सकते हैं?

अपने जवाब की जांच करें

यह नीचे दी गई लाइन है: espresso = 30 * cup; water = 70 * cup;

इस टेस्ट में नौ में से सिर्फ़ पांच स्टेटमेंट शामिल किए गए हैं. इसलिए, स्टेटमेंट कवरेज 55.55% है.

अगर आप हमेशा एक लाइन में एक स्टेटमेंट लिखते हैं, तो आपकी लाइन की कवरेज भी आपके स्टेटमेंट कवरेज की तरह ही होगी.

आपको किस तरह का कोड कवरेज चुनना चाहिए?

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

सामान्य तौर पर, स्टेटमेंट कवरेज एक अच्छा शुरुआती पॉइंट है, क्योंकि यह आसान और समझने में आसान मेट्रिक है. स्टेटमेंट कवरेज, ब्रांच कवरेज और फ़ंक्शन कवरेज से यह मेज़र किया जाता है कि टेस्ट किसी शर्त (ब्रांच) को कॉल करते हैं या फ़ंक्शन को. इसलिए, स्टेटमेंट कवरेज के बाद में इस तरह से बदलाव होना एक सामान्य बात है.

ज़्यादा स्टेटमेंट कवरेज मिलने के बाद, ब्रांच कवरेज और फ़ंक्शन कवरेज का इस्तेमाल करें.

क्या टेस्ट कवरेज और कोड कवरेज एक ही होता है?

नहीं. टेस्ट कवरेज और कोड कवरेज में भ्रम की स्थिति होती है, लेकिन वे अलग-अलग होती हैं:

  • टेस्ट कवरेज: ऐक्वालिटेटिव मेट्रिक जो मापती है कि टेस्ट सुइट, सॉफ़्टवेयर की सुविधाओं को कितनी अच्छी तरह से कवर करता है. इससे इस बात का पता लगाने में मदद मिलती है कि इसमें किस स्तर का जोखिम है.
  • कोड कवरेज: यह एक क्वांटिटेटिव मेट्रिक होती है. यह टेस्टिंग के दौरान लागू किए गए कोड के अनुपात को मापती है. यह इस बारे में होता है कि टेस्ट में कितने कोड शामिल हैं.

यहां सरल तरीके से साेच दिया गया है: वेब ऐप्लिकेशन को एक घर के तौर पर मानें.

  • टेस्ट कवरेज से यह पता चलता है कि टेस्ट, घर के कमरों को कितनी अच्छी तरह से कवर करते हैं.
  • कोड कवरेज की मदद से यह पता चलता है कि टेस्ट में घर का कितना हिस्सा पार हुआ है.

100% कोड कवरेज का मतलब यह नहीं है कि कोई गड़बड़ी नहीं है

टेस्टिंग में हाई कोड कवरेज पाना ज़रूरी है. हालांकि, 100% कोड कवरेज इस बात की गारंटी नहीं देता कि आपके कोड में कोई गड़बड़ी या खामियां नहीं होंगी.

100% कोड कवरेज पाने का कोई मतलब नहीं है

नीचे दिया गया तरीका आज़माएं:

/* coffee.test.js */

// ...
describe('Warning: Do not do this', () => {
  it('is meaningless', () => { 
    calcCoffeeIngredient('espresso', 2);
    calcCoffeeIngredient('americano');
    calcCoffeeIngredient('unknown');
    isValidCoffee('mocha');
    expect(true).toBe(true); // not meaningful assertion
  });
});

इस टेस्ट से 100% फ़ंक्शन, लाइन, ब्रांच, और स्टेटमेंट कवरेज मिलती है, लेकिन इसका कोई मतलब नहीं है, क्योंकि यह कोड की जांच नहीं करता. expect(true).toBe(true) दावा हमेशा पास हो जाएगा, भले ही कोड सही तरीके से काम कर रहा हो.

खराब मेट्रिक, बिना मेट्रिक के खराब होती है

एक खराब मेट्रिक आपको सुरक्षा का झूठा एहसास दिला सकती है, जो बिना मेट्रिक के न होने से भी ज़्यादा खराब है. उदाहरण के लिए, अगर आपके पास ऐसा टेस्ट सुइट है जो 100% कोड कवरेज हासिल कर लेता है, लेकिन सभी टेस्ट काम के नहीं हैं, तो हो सकता है कि आपको सुरक्षा के बारे में गलत जानकारी हो. इसका मतलब है कि आपके कोड की अच्छी तरह से जांच की गई है. अगर ऐप्लिकेशन कोड के किसी हिस्से को गलती से मिटाया या भंग किया जाता है, तो जांच में पास हो जाएंगे. भले ही, ऐप्लिकेशन अब ठीक से काम न कर रहा हो.

इस स्थिति से बचने के लिए:

  • समीक्षा की जांच करें. टेस्ट लिखें और उनकी समीक्षा करें, ताकि यह पक्का किया जा सके कि वे काम के हों. साथ ही, अलग-अलग स्थितियों में कोड की जांच करें.
  • कोड कवरेज का इस्तेमाल दिशा-निर्देश के तौर पर करें, न कि सिर्फ़ जांच के असर या कोड की क्वालिटी को मापने के तरीके के तौर पर.

अलग-अलग तरह की टेस्टिंग में कोड कवरेज का इस्तेमाल करना

आइए, देखते हैं कि तीन सामान्य तरह के टेस्ट के साथ, कोड कवरेज का इस्तेमाल कैसे किया जा सकता है:

  • यूनिट टेस्ट. कोड कवरेज इकट्ठा करने के लिए, टेस्ट टाइप सबसे बेहतर होते हैं. इसकी वजह यह है कि इन्हें कई छोटी स्थितियों और टेस्टिंग पाथ को कवर करने के लिए डिज़ाइन किया जाता है.
  • इंटिग्रेशन की जांच. इनसे, इंटिग्रेशन की जांच के लिए कोड कवरेज इकट्ठा करने में मदद मिल सकती है. हालांकि, उनका इस्तेमाल सावधानी से करें. इस मामले में, सोर्स कोड के बड़े हिस्से की कवरेज का हिसाब लगाया जाता है. इससे यह तय करना मुश्किल हो सकता है कि कौनसे टेस्ट में कोड के कौनसे हिस्से शामिल हैं. इसके बावजूद, इंटिग्रेशन टेस्ट के लिए कोड कवरेज का हिसाब लगाना, लेगसी सिस्टम के लिए मददगार हो सकता है. ऐसा उन लेगसी सिस्टम के लिए किया जा सकता है जिनमें अलग-अलग यूनिट नहीं होती हैं.
  • एंड-टू-एंड (E2E) टेस्ट. इन टेस्ट में जटिल तरीके की वजह से, E2E टेस्ट के लिए कोड कवरेज को मेज़र करना मुश्किल और चुनौती भरा होता है. कोड कवरेज का इस्तेमाल करने के बजाय, ज़रूरत के हिसाब से कवरेज देना एक बेहतर तरीका हो सकता है. ऐसा इसलिए होता है, क्योंकि E2E टेस्ट में टेस्ट से जुड़ी ज़रूरी शर्तों को शामिल किया जाता है, न कि सोर्स कोड पर.

नतीजा

कोड कवरेज, जांच के असर को मेज़र करने में मदद करने वाली मेट्रिक हो सकती है. इससे आपको यह पक्का करने में मदद मिल सकती है कि आपके कोड के ज़रूरी लॉजिक को अच्छी तरह से टेस्ट किया गया है. इससे, ऐप्लिकेशन की क्वालिटी को बेहतर बनाया जा सकता है.

हालांकि, याद रखें कि कोड कवरेज सिर्फ़ एक मेट्रिक होती है. पक्का करें कि आपको कुछ अन्य बातों को भी ध्यान में रखना चाहिए. जैसे, आपकी जांच की क्वालिटी और आवेदन करने से जुड़ी ज़रूरी शर्तें.

कोड को 100% कवरेज देने का लक्ष्य नहीं है. इसके बजाय, आपको एक ऐसे टेस्टिंग प्लान के साथ कोड कवरेज का इस्तेमाल करना चाहिए जिसमें कई तरह की टेस्टिंग के तरीके शामिल हों. जैसे, यूनिट टेस्ट, इंटिग्रेशन टेस्ट, एंड-टू-एंड टेस्ट, और मैन्युअल टेस्ट.

कोड का पूरा उदाहरण देखें और अच्छे कोड कवरेज वाले टेस्ट देखें. इस लाइव डेमो की मदद से, कोड चलाकर जांच भी की जा सकती है.

/* coffee.js - a complete example */

export function calcCoffeeIngredient(coffeeName, cup = 1) {
  if (!isValidCoffee(coffeeName)) return {};

  let espresso, water;

  if (coffeeName === 'espresso') {
    espresso = 30 * cup;
    return { espresso };
  }

  if (coffeeName === 'americano') {
    espresso = 30 * cup; water = 70 * cup;
    return { espresso, water };
  }

  throw new Error (`${coffeeName} not found`);
}

function isValidCoffee(name) {
  return ['espresso', 'americano', 'mocha'].includes(name);
}
/* coffee.test.js - a complete test suite */

import { describe, expect, it } from 'vitest';
import { calcCoffeeIngredient } from '../src/coffee-complete';

describe('Coffee', () => {
  it('should have espresso', () => {
    const result = calcCoffeeIngredient('espresso', 2);
    expect(result).to.deep.equal({ espresso: 60 });
  });

  it('should have americano', () => {
    const result = calcCoffeeIngredient('americano');
    expect(result.espresso).to.equal(30);
    expect(result.water).to.equal(70);
  });

  it('should throw error', () => {
    const func = () => calcCoffeeIngredient('mocha');
    expect(func).toThrowError(new Error('mocha not found'));
  });

  it('should have nothing', () => {
    const result = calcCoffeeIngredient('unknown')
    expect(result).to.deep.equal({});
  });
});