आप जानते हैं कि खराब परीक्षण किए गए कोड के साथ काम करना कितना दर्दनाक है। हर बार जब आप कोई बग ठीक करते हैं, तो आप पांच और बनाते हैं। और जब चीज़ें करें काम, आप वास्तव में कभी नहीं जानते कि क्या इसे इस तरह से डिज़ाइन किया गया था, या बस संयोग से काम किया।
दूसरी ओर, आपने अभी-अभी लिखा है कि एक छोटी सी विशेषता को शिप करने के लिए 200 परीक्षण कैसा लगता है। 100% परीक्षण कवरेज को हिट करने के लिए आपको लगातार पहले से काम कर रहे कोड को फिर से डिज़ाइन करना होगा। आप यह महसूस नहीं कर सकते कि आपका सबसे अच्छा परीक्षण किया गया कोड किसी तरह कम हो रहा है पढ़ने योग्य और सबसे बुरी बात यह है कि आप अपने ऐप पर बर्न आउट होने लगे हैं।
बीच का रास्ता होना चाहिए। तो कितना परीक्षण सही राशि है?
यह बहुत अच्छा होगा यदि कोई अच्छा राउंड नंबर था जिसे आप एक नियम के रूप में उपयोग कर सकते हैं:ऐप कोड के रूप में परीक्षण कोड की दो बार, शायद, या 95% परीक्षण कवरेज। लेकिन "95% परीक्षण कवरेज" कहना भी अस्पष्ट है।
कवरेज एक संकेतक . हो सकता है अच्छी तरह से परीक्षित कोड का, लेकिन यह गारंटी नहीं है अच्छी तरह से परीक्षण किए गए कोड का। मेरे पास 100% कवर किए गए ऐप्स हैं जिनमें 85% कवरेज वाले ऐप्स की तुलना में अधिक बग थे।
इसलिए, परीक्षण की सही मात्रा एक संख्या के बारे में नहीं हो सकती है। इसके बजाय, यह कुछ अस्पष्ट और परिभाषित करने में कठिन है। यह कुशलतापूर्वक का परीक्षण करने के बारे में है .
कुशल परीक्षण
कुशलता से परीक्षण करना कम से कम काम के लिए सबसे अधिक लाभ प्राप्त करने के बारे में है। बहुत अच्छा लगता है, है ना?
लेकिन बहुत कुछ है जो अधिक कुशलता से परीक्षण में जाता है। इसलिए यह विशेष रूप से तीन चीजों के बारे में सोचने में मदद करता है:आकार, अलगाव और फोकस।
आकार
एकीकरण परीक्षण कमाल के हैं। वे उस पथ को प्रतिबिंबित करते हैं जो एक वास्तविक व्यक्ति आपके ऐप के माध्यम से लेता है। वे आपके सभी कोड का परीक्षण करते हैं, एक साथ काम करते हुए, उसी तरह जैसे वास्तविक दुनिया में इसका उपयोग किया जाता है।
लेकिन एकीकरण परीक्षण धीमे हैं। वे लंबे और गन्दा हो सकते हैं। और अगर आप अपने सिस्टम के एक छोटे से हिस्से का पूरी तरह से परीक्षण करना चाहते हैं, तो वे बहुत अधिक ओवरहेड जोड़ देते हैं।
यूनिट परीक्षण छोटे होते हैं। वे तेज दौड़ते हैं। उनके बारे में सोचना आसान है, क्योंकि उन्हें लिखते समय आपको अपने सिस्टम का केवल एक छोटा सा हिस्सा अपने दिमाग में रखना होता है।
लेकिन वे नकली भी हो सकते हैं। सिर्फ इसलिए कि यूनिट टेस्ट के अंदर कुछ काम करता है इसका मतलब यह नहीं है कि यह वास्तविक दुनिया में भी काम करेगा। (खासकर यदि आप बहुत मज़ाक कर रहे हैं)।
तो आप उन्हें कैसे संतुलित करते हैं?
चूंकि यूनिट परीक्षण तेज और लिखने में आसान होते हैं, इसलिए उनमें से बहुत से होने में अधिक खर्च नहीं होता है। इसलिए वे किनारे के मामलों और जटिल तर्क जैसी चीजों का परीक्षण करने के लिए एक शानदार जगह हैं।
एक बार जब आपके पास अपने सिस्टम के अच्छी तरह से परीक्षण किए गए टुकड़ों का एक गुच्छा होता है, तब भी आपको अंतराल को भरना होगा। आपको परीक्षण करना होगा कि वे भाग कैसे इंटरैक्ट करते हैं, और पूरी यात्रा जो कोई आपके ऐप के माध्यम से कर सकता है। लेकिन चूंकि आपके अधिकांश एज केस और लॉजिक का परीक्षण आपके यूनिट परीक्षणों द्वारा किया जाता है, इसलिए आपको इनमें से कुछ अधिक जटिल, धीमे एकीकरण परीक्षणों की आवश्यकता है।
आपको "टेस्ट पिरामिड" नामक यह विचार सुनाई देगा। यह कुछ एकीकरण परीक्षण हैं, जो कई यूनिट परीक्षणों के आधार पर शीर्ष पर बैठे हैं। और अगर आप इसके बारे में और जानना चाहते हैं, तो मेरी किताब, प्रैक्टिसिंग रेल्स के तीसरे अध्याय पर एक नज़र डालें।
अलगाव
फिर भी, यदि आपका सिस्टम जटिल है, तो आपके द्वारा चलाई जा सकने वाली हर स्थिति को कवर करने के लिए अनंत संख्या में परीक्षणों की तरह लग सकता है। यह एक संकेत हो सकता है कि आपको अपने ऐप के डिज़ाइन पर पुनर्विचार करने की आवश्यकता है। इसका मतलब है कि आपके सिस्टम के हिस्से एक-दूसरे पर बहुत अधिक निर्भर हैं।
मान लें कि आपके पास एक ऐसी वस्तु है जो कुछ भिन्न अवस्थाओं में से किसी एक में हो सकती है:
case user.type
when :admin
message = admin_message
when :user
message = user_message
when :author
message = author_message
else
message = anonymous_message
end
if user.preferred_notification_method = :email
send_email(message)
elsif user.preferred_notification_method = :text
send_text_message(message)
else
queue_notification(message)
end
यदि आप यहां हर संभव पथ का परीक्षण करना चाहते हैं, तो आपके पास परीक्षण करने के लिए 12 अलग-अलग स्थितियां होंगी:
- उपयोगकर्ता एक व्यवस्थापक है,
preferred_notification_method
ईमेल है - उपयोगकर्ता एक व्यवस्थापक है,
preferred_notification_method
टेक्स्ट है - उपयोगकर्ता एक व्यवस्थापक है,
preferred_notification_method
न तो है - उपयोगकर्ता एक उपयोगकर्ता है,
preferred_notification_method
ईमेल है - उपयोगकर्ता एक उपयोगकर्ता है,
preferred_notification_method
टेक्स्ट है - उपयोगकर्ता एक उपयोगकर्ता है,
preferred_notification_method
न तो है - उपयोगकर्ता एक लेखक है,
preferred_notification_method
ईमेल है - उपयोगकर्ता एक लेखक है,
preferred_notification_method
टेक्स्ट है - उपयोगकर्ता एक लेखक है,
preferred_notification_method
न तो है - उपयोगकर्ता अनाम है,
preferred_notification_method
ईमेल है - उपयोगकर्ता अनाम है,
preferred_notification_method
टेक्स्ट है - उपयोगकर्ता अनाम है,
preferred_notification_method
न तो है
परीक्षण करने के लिए बहुत सारे मामले हैं क्योंकि "अधिसूचना पद्धति के आधार पर संदेश भेजना" और "उपयोगकर्ता के प्रकार के आधार पर संदेश उत्पन्न करना" एक साथ बंधे हैं। आप शायद कम के साथ निचोड़ने में सक्षम हो, लेकिन यह स्पष्ट नहीं है - और यह सिर्फ बग के लिए पूछ रहा है।
लेकिन क्या होगा अगर आपने उन्हें अलग कर दिया?
message = get_message_based_on_user_type(user.type)
send_notification(message, user.preferred_notification_method)
अब आप प्रत्येक भाग का अलग-अलग परीक्षण कर सकते हैं।
पहले भाग के लिए, आप परीक्षण कर सकते हैं कि प्रत्येक प्रकार के उपयोगकर्ता के लिए सही संदेश दिया गया है।
दूसरे भाग के लिए, आप जांच सकते हैं कि दिया गया संदेश preferred_notification_method
के मान के आधार पर सही ढंग से भेजा गया है। ।
और अंत में, आप परीक्षण कर सकते हैं कि मूल विधि do_stuff_based_on_user_type
से लौटाए गए संदेश को पास कर देगी send_email_or_text
. के साथ . तो अब, आपके पास परीक्षण करने के लिए 8 राज्य हैं:
- उपयोगकर्ता एक व्यवस्थापक है
- उपयोगकर्ता एक उपयोगकर्ता है
- उपयोगकर्ता एक लेखक है
- उपयोगकर्ता गुमनाम है
preferred_notification_method
ईमेल हैpreferred_notification_method
टेक्स्ट हैpreferred_notification_method
न तो है- और मूल विधि के लिए एक परीक्षण
यहां, आप कोड को अलग करके चार परीक्षण सहेजते हैं ताकि आप इसे अलग से परीक्षण कर सकें। दूसरे उदाहरण में, यह बहुत अधिक स्पष्ट है कि आप कम परीक्षणों के द्वारा प्राप्त कर सकते हैं। और आप कल्पना कर सकते हैं कि जैसे-जैसे आप अधिक राज्यों को जोड़ते हैं, अपने कोड को विभाजित करना और भी बेहतर विचार बन जाता है।
अलगाव और पठनीयता के बीच सबसे अच्छा संतुलन खोजने से पहले आपको समय और अभ्यास लगता है। लेकिन अगर आप अपनी निर्भरता को सही जगह पर तोड़ते हैं, तो आप बहुत कम परीक्षणों के साथ आगे बढ़ सकते हैं।
फोकस करें
आपका ऐप अच्छी तरह से परीक्षण किया जाना चाहिए। लेकिन इसका मतलब यह नहीं है कि आपके ऐप के हर हिस्से को अपने परीक्षणों पर समान ध्यान देने योग्य है।
भले ही आप 100% परीक्षण कवरेज का लक्ष्य रखते हों, फिर भी आपने हर चीज़ का परीक्षण नहीं किया। उदाहरण के लिए, आप शायद अपने विचारों में पाठ की प्रत्येक पंक्ति का परीक्षण नहीं करेंगे, या कि आप दस के बजाय हर पांच सेकंड में अपडेट के लिए मतदान कर रहे हैं।
यहीं पर ध्यान केंद्रित होता है। कम, अधिक उपयोगी परीक्षण लिखना। और सोच-समझकर निर्णय लेना कि आप अपना सबसे अच्छा समय कहाँ बिता सकते हैं।
फोकस एक और चीज है जिसे ठीक करना मुश्किल है। ये कुछ सवाल हैं जो मैं खुद से पूछता हूं जो मुझे सबसे महत्वपूर्ण परीक्षणों पर ध्यान केंद्रित करने में मदद करते हैं:
-
यह मेरे बाकी ऐप से कितना इंटरकनेक्टेड है? अगर यह टूट जाता है, तो इसके साथ और कितने टुकड़े गिरेंगे?
-
यह कितनी संभावना है कि यह स्वाभाविक रूप से बदल जाएगा? अगर मेरे परीक्षण विफल हो जाते हैं, तो क्या यह किसी बग के कारण होगा, या किसी ने UI में कुछ टेक्स्ट अपडेट करने के कारण?
-
इस टूटने का क्या असर है? क्या मैं किसी के क्रेडिट कार्ड से दो बार शुल्क लेने जा रहा हूँ, या यह बस कुछ लापता पाठ के साथ समाप्त होने वाला है?
-
इस भाग का कितनी बार उपयोग किया जाता है? क्या यह ऐप के व्यवहार के लिए महत्वपूर्ण है, या यह एक पेज के बारे में है जो पाद लेख में कहीं दब गया है?
आपको केवल नहीं करना चाहिए महत्वपूर्ण भागों का परीक्षण करें। लेकिन आपके पास एक ऐसा ऐप होगा जो महसूस यदि आप अपना परीक्षण समय अच्छी तरह से व्यतीत करते हैं तो उच्च गुणवत्ता।
यदि आप हर संभव पथ का परीक्षण करने का प्रयास करते हैं जो कोई आपके ऐप के माध्यम से ले सकता है, तो आप कभी भी शिप नहीं करेंगे। TDD मदद करता है, लेकिन यह आपकी सभी परीक्षण समस्याओं का समाधान नहीं करेगा।
बेशक, इसका मतलब यह नहीं है कि आपको बिल्कुल भी परीक्षण नहीं करना चाहिए।
आप अपने परीक्षणों को छोटा रखने के लिए परीक्षण पिरामिड का उपयोग कर सकते हैं। आप m * n
. को चालू करने के लिए निर्भरता को अलग और तोड़ सकते हैं परीक्षण मामलों में m + n
. और आप प्राथमिकता दे सकते हैं, ताकि आप अपने ऐप के सबसे महत्वपूर्ण हिस्सों का परीक्षण करने में अधिक समय व्यतीत कर सकें।
तो, आप . कितना करते हैं परीक्षण? अपना ऐप बनाते समय क्या आप इनमें से किसी भी विचार पर विचार करते हैं? और आप कैसे जानते हैं कि आपके ऐप के किन हिस्सों पर ध्यान केंद्रित करना है? एक टिप्पणी छोड़ें और मुझे इसके बारे में सब कुछ बताएं!