जांच करने या न करने के बारे में, तकनीकी जानकारी

तय करें कि आपको किस चीज़ की जांच करनी है और किस चीज़ को बाहर रखा जा सकता है.

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

क्या टेस्ट करना है या क्या नहीं.

सामान्य दिशा-निर्देश और पैटर्न

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

इसे आसान रखें

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

अगर आपके पास कम हेडस्पेस है, तो हो सकता है कि आप टेस्टिंग के दौरान ज़्यादा आराम महसूस करें. इसलिए, टेस्टिंग में आसानी को प्राथमिकता देना ज़रूरी है. असल में, Yoni Goldberg के JavaScript टेस्टिंग के सबसे सही तरीके, इस बात पर ज़ोर देते हैं कि यह सबसे अहम नियम है—आपका टेस्ट, किसी सहायक की तरह होना चाहिए, न कि किसी जटिल गणितीय फ़ॉर्मूला की तरह. दूसरे शब्दों में, आपको पहली नज़र में अपने टेस्ट का मकसद समझ आ जाना चाहिए.

टेस्ट को मुश्किल न बनाएं, ताकि उन्हें ऐसा न लगे.

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

इस नज़रिए से देखें: किसी टेस्ट के नतीजे के गलत होने पर, यह आसानी से पता चल जाना चाहिए कि क्या गड़बड़ी हुई है. इसलिए, टेस्ट को आसान और समझने लायक बनाना ज़रूरी है. ऐसा करने से, समस्याएं होने पर उन्हें तुरंत पहचाना और ठीक किया जा सकता है.

देखें कि कौनसी चीज़ें काम की हैं

फ़्लैट टेस्ट डिज़ाइन से, फ़ोकस करने में भी मदद मिलती है. साथ ही, इससे यह पक्का करने में भी मदद मिलती है कि आपके टेस्ट काम के हों. याद रखें कि आपको सिर्फ़ कवरेज के लिए टेस्ट नहीं बनाने हैं—उनका हमेशा कोई मकसद होना चाहिए.

सभी चीज़ों की जांच न करें.

लागू करने से जुड़ी जानकारी की जांच न करें

टेस्टिंग में एक आम समस्या यह है कि टेस्ट को अक्सर लागू करने की जानकारी की जांच करने के लिए डिज़ाइन किया जाता है. जैसे, कॉम्पोनेंट में सिलेक्टर का इस्तेमाल करना या एंड-टू-एंड टेस्ट. लागू करने की जानकारी में ऐसी चीज़ों के बारे में बताया जाता है जिनका इस्तेमाल, आम तौर पर आपके कोड के उपयोगकर्ता नहीं करते. साथ ही, वे इन चीज़ों को नहीं देखते और इनके बारे में उन्हें पता भी नहीं होता. इसकी वजह से, टेस्ट में दो बड़ी समस्याएं आ सकती हैं: गलत नेगेटिव और गलत पॉज़िटिव.

गलत नेगेटिव तब होते हैं, जब टेस्ट पूरा नहीं होता. भले ही, टेस्ट किया गया कोड सही हो. ऐसा तब हो सकता है, जब ऐप्लिकेशन कोड को फिर से बनाने की वजह से, लागू करने की जानकारी बदल जाए. दूसरी ओर, फ़ॉल्स पॉज़िटिव तब होता है, जब टेस्ट पास हो जाता है, भले ही टेस्ट किया जा रहा कोड गलत हो.

इस समस्या का एक समाधान यह है कि आप अपने अलग-अलग तरह के उपयोगकर्ताओं को ध्यान में रखें. असली उपयोगकर्ता और डेवलपर के दृष्टिकोण अलग-अलग हो सकते हैं. साथ ही, वे कोड के साथ अलग-अलग तरीके से इंटरैक्ट कर सकते हैं. टेस्ट की योजना बनाते समय, यह ध्यान रखना ज़रूरी है कि उपयोगकर्ताओं को क्या दिखेगा या वे किससे इंटरैक्ट करेंगे. साथ ही, टेस्ट को लागू करने की जानकारी के बजाय, उन चीज़ों पर निर्भर बनाएं.

उदाहरण के लिए, ऐसे सिलेक्टर चुनने से टेस्ट ज़्यादा भरोसेमंद हो सकते हैं जिनमें बदलाव होने की संभावना कम होती है: सीएसएस सिलेक्टर के बजाय डेटा-एट्रिब्यूट. ज़्यादा जानकारी के लिए, Kent C. Dodds का लेख पढ़ें या हमारे साथ बने रहें—इस विषय पर एक लेख जल्द ही पब्लिश किया जाएगा.

मॉकिंग: कंट्रोल न खोएं

मॉकिंग एक ऐसा कॉन्सेप्ट है जिसका इस्तेमाल यूनिट टेस्टिंग और कभी-कभी इंटिग्रेशन टेस्टिंग में किया जाता है. इसमें, नकली डेटा या कॉम्पोनेंट बनाकर, उन डिपेंडेंसी को सिम्युलेट करना शामिल है जिनका ऐप्लिकेशन पर पूरा कंट्रोल होता है. इससे अलग-अलग टेस्टिंग की जा सकती है.

अपने टेस्ट में मॉक का इस्तेमाल करने से, अनुमान लगाने की सुविधा, अलग-अलग समस्याओं को अलग करने की सुविधा, और परफ़ॉर्मेंस को बेहतर बनाया जा सकता है. अगर आपको ऐसा टेस्ट करना है जिसमें किसी व्यक्ति की ज़रूरत पड़ती है, जैसे कि पासपोर्ट की पुष्टि, तो आपको मॉक का इस्तेमाल करके उसे छिपाना होगा. इन सभी वजहों से, मॉक एक अहम टूल है.

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

क्या आपको एंड-टू-एंड टेस्ट में मॉकिंग का इस्तेमाल करना चाहिए?

आम तौर पर, नहीं. हालांकि, मॉकिंग कभी-कभी काम की हो सकती है—इसलिए, इसे पूरी तरह से खारिज न करें.

इस स्थिति की कल्पना करें: आपको पेमेंट की सुविधा देने वाली तीसरे पक्ष की सेवा से जुड़ी किसी सुविधा के लिए टेस्ट लिखना है. आप उस सैंडबॉक्स एनवायरमेंट में हैं जिसे उन्होंने उपलब्ध कराया है. इसका मतलब है कि कोई असल लेन-देन नहीं हो रहा है. माफ़ करें, सैंडबॉक्स ठीक से काम नहीं कर रहा है. इस वजह से, आपके टेस्ट पूरे नहीं हो पा रहे हैं. पेमेंट की सेवा देने वाली कंपनी को यह समस्या ठीक करनी होगी. आपको बस सेवा देने वाली कंपनी से समस्या हल होने का इंतज़ार करना होगा.

ऐसे में, उन सेवाओं पर निर्भरता कम करना ज़्यादा फ़ायदेमंद हो सकता है जिन्हें आपके पास कंट्रोल करने का विकल्प नहीं है. हालांकि, हमारा सुझाव है कि इंटिग्रेशन या एंड-टू-एंड टेस्ट में, मॉकिंग का इस्तेमाल सावधानी से करें. ऐसा इसलिए, क्योंकि इससे आपके टेस्ट का कॉन्फ़िडेंस लेवल कम हो जाता है.

टेस्ट से जुड़ी खास जानकारी: क्या करें और क्या न करें

तो, कुल मिलाकर, टेस्ट में क्या शामिल होता है? क्या जांच के अलग-अलग टाइप में अंतर है? आइए, टेस्टिंग के मुख्य टाइप के हिसाब से, कुछ खास पहलुओं पर नज़र डालते हैं.

अच्छी यूनिट टेस्ट में क्या शामिल होता है?

किसी यूनिट टेस्ट को बेहतर और असरदार बनाने के लिए:

  • खास पहलुओं पर ध्यान दें.
  • अपने-आप काम करना.
  • छोटे पैमाने पर होने वाली स्थितियों को शामिल करें.
  • पूरी जानकारी देने वाले नामों का इस्तेमाल करें.
  • अगर लागू हो, तो AAA पैटर्न का पालन करें.
  • पूरी जांच की गारंटी.
ऐसा करें ✅ ऐसा न करें ❌
टेस्ट को जितना हो सके उतना छोटा रखें. हर टेस्ट केस के लिए एक चीज़ की जांच करें. बड़ी इकाइयों के लिए टेस्ट लिखें.
टेस्ट को हमेशा अलग-अलग रखें और अपनी यूनिट से बाहर की ज़रूरी चीज़ों का मॉक अप बनाएं. अन्य कॉम्पोनेंट या सेवाएं शामिल करें.
टेस्ट को अलग-अलग रखें. पिछले टेस्ट पर भरोसा करें या टेस्ट का डेटा शेयर करें.
अलग-अलग स्थितियों और पाथ को कवर करें. ज़्यादा से ज़्यादा, हैप्पी पाथ या नेगेटिव टेस्ट तक ही सीमित रहें.
टेस्ट के लिए ऐसे टाइटल इस्तेमाल करें जिनसे तुरंत पता चल जाए कि टेस्ट किस बारे में है. सिर्फ़ फ़ंक्शन के नाम से टेस्ट किया गया, जिससे नतीजे के बारे में ज़्यादा जानकारी नहीं मिल रही है: testBuildFoo() या testGetId().
खास तौर पर इस चरण में, अच्छी कोड कवरेज या टेस्ट केस की एक बड़ी रेंज का लक्ष्य रखें. हर क्लास से लेकर डेटाबेस (I/O) लेवल तक की जांच करें.

इंटिग्रेशन टेस्ट में क्या शामिल होता है?

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

  • कॉम्पोनेंट के बीच इंटरैक्शन को सिम्युलेट करना.
  • असल दुनिया की स्थितियों को कवर करें और मॉक या स्टब का इस्तेमाल करें.
  • परफ़ॉर्मेंस पर ध्यान दें.
ऐसा करें ✅ ऐसा न करें ❌
इंटिग्रेशन पॉइंट की जांच करें: पुष्टि करें कि एक-दूसरे के साथ इंटिग्रेट होने पर, हर यूनिट एक साथ सही तरीके से काम करती है. हर यूनिट को अलग से टेस्ट करें—यही यूनिट टेस्ट के लिए ज़रूरी है.
असल दुनिया के उदाहरणों की जांच करना: असल दुनिया के डेटा से मिले टेस्ट डेटा का इस्तेमाल करें. अपने-आप जनरेट होने वाले टेस्ट डेटा या ऐसे अन्य डेटा का इस्तेमाल करना जो असल दुनिया में इस्तेमाल के उदाहरणों को नहीं दिखाता.
अपने पूरे टेस्ट को कंट्रोल करने के लिए, बाहरी डिपेंडेंसी के लिए मॉक और स्टब का इस्तेमाल करें. तीसरे पक्ष की सेवाओं पर निर्भरता बनाएं. उदाहरण के लिए, बाहरी सेवाओं के लिए नेटवर्क अनुरोध.
हर टेस्ट से पहले और बाद में, क्लीन-अप रूटीन का इस्तेमाल करें. अपने टेस्ट में क्लीन-अप मेज़र का इस्तेमाल करना न भूलें. ऐसा न करने पर, टेस्ट के सही तरीके से अलग न होने की वजह से, टेस्ट पूरा न हो पाना या गलत नतीजे मिलना मुमकिन है.

अच्छे एंड-टू-एंड टेस्ट में क्या शामिल होता है?

शुरू से आखिर तक की पूरी जांच में ये चीज़ें होनी चाहिए:

  • उपयोगकर्ता के इंटरैक्शन को दोहराना.
  • ज़रूरी स्थितियों को शामिल करें.
  • एक से ज़्यादा लेयर में मौजूद हों.
  • एसिंक्रोनस ऑपरेशन मैनेज करना.
  • नतीजों की पुष्टि करें.
  • परफ़ॉर्मेंस को ध्यान में रखें.
ऐसा करें ✅ ऐसा न करें ❌
एपीआई से चलने वाले शॉर्टकट का इस्तेमाल करें. ज़्यादा जानें. हर चरण के लिए यूज़र इंटरफ़ेस (यूआई) इंटरैक्शन का इस्तेमाल करें. इसमें beforeEach हुक भी शामिल है.
हर टेस्ट से पहले, क्लीन-अप रूटीन का इस्तेमाल करें. यूनिट और इंटिग्रेशन टेस्ट के मुकाबले, टेस्ट को अलग-अलग रखने में ज़्यादा ध्यान रखें. इसकी वजह यह है कि यहां साइड इफ़ेक्ट का खतरा ज़्यादा होता है. हर टेस्ट के बाद क्लीन अप करना न भूलें. अगर आपने बाकी बचे स्टेटस, डेटा या साइड इफ़ेक्ट को साफ़ नहीं किया, तो उनसे बाद में चलाए जाने वाले अन्य टेस्ट पर असर पड़ेगा.
शुरू से आखिर तक के टेस्ट को सिस्टम टेस्ट मानें. इसका मतलब है कि आपको पूरे ऐप्लिकेशन स्टैक की जांच करनी होगी. हर यूनिट को अलग से टेस्ट करें—यही यूनिट टेस्ट के लिए ज़रूरी है.
टेस्ट में कम से कम या कोई मॉकिंग का इस्तेमाल न करें. अगर आपको बाहरी डिपेंडेंसी का मॉक बनाना है, तो इस बारे में सोच-समझकर फ़ैसला लें. मॉक टेस्ट पर ज़्यादा भरोसा करना.
परफ़ॉर्मेंस और वर्कलोड पर ध्यान दें. उदाहरण के लिए, एक ही टेस्ट में बड़े सिनेरियो की ज़्यादा टेस्टिंग न करें. शॉर्टकट का इस्तेमाल किए बिना, बड़े वर्कफ़्लो कवर करें.