Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

परतदार परीक्षण सूट का मामला

मैंने हाल ही में एक परीक्षण सूट पर काम किया है जो अविश्वसनीय होने के कारण उपयोग करने के लिए वास्तव में निराशाजनक था।

परीक्षण सूट जिस एप्लिकेशन को लक्षित कर रहा था वह एक रेल एपीआई-केवल एप्लिकेशन था। परीक्षण जावास्क्रिप्ट में चक्रम नामक ढांचे का उपयोग करके लिखे गए थे, "JSON REST एंडपॉइंट्स पर एंड टू एंड टेस्ट करने के लिए डिज़ाइन किया गया एक एपीआई परीक्षण ढांचा"।

परीक्षण सूट के साथ समस्या यह थी कि यह नियतात्मक नहीं था। एक फ़ंक्शन या प्रोग्राम नियतात्मक होता है यदि, समान इनपुट दिए जाने पर, यह हमेशा समान आउटपुट देता है।

यह विशेष परीक्षण सूट पहले रन पर पास होगा, दूसरे रन पर पास होगा, फिर तीसरे रन पर विफल हो जाएगा, बिना एप्लिकेशन कोड या टेस्ट कोड में बदलाव किए बिना।

मैंने पाया कि मैं एक rake db:reset करके टेस्ट सूट को वापस पासिंग में ला सकता हूं . परीक्षण, जो रेल अनुप्रयोग के विकास परिवेश पर संचालित होता है, न कि परीक्षण परिवेश पर, यह इस बात पर निर्भर करता है कि परीक्षण सूट के चलने के समय रेल अनुप्रयोग का डेटाबेस एक निश्चित स्थिति में है।

कभी-कभी मैं एक ताजा वरीयता प्राप्त डेटाबेस से शुरू कर सकता था, परीक्षण सूट चला सकता था, और फिर दूसरी बार सफलतापूर्वक परीक्षण सूट चला सकता था। मैं परीक्षण सूट को तीन या अधिक बार चलाने में सक्षम हो सकता हूं। लेकिन अक्सर, परीक्षण सूट किसी भी तरह डेटा को गड़बड़ कर देता है और मुझे एक और rake db:reset करना होगा। डेटा को उस स्थिति में वापस लाने के लिए जिसका परीक्षण सूट सफलतापूर्वक उपयोग कर सकता है।

यह बिल्कुल नहीं है कि चीजें कैसी होनी चाहिए। एक परीक्षण सूट केवल एक कारण से विफल होना चाहिए:जिस कोड का वह परीक्षण कर रहा है वह ठीक से काम करना बंद कर देता है।

इसके बजाय क्या किया जाना चाहिए था

तो अगर यह परीक्षण सूट एक समस्याग्रस्त तरीके से स्थापित किया गया था, तो क्या इसे करने का सही तरीका होता?

समस्या की जड़ यह थी कि परीक्षण सूट मानव द्वारा मैन्युअल रूप से किए जा रहे डेटाबेस रीसेट पर निर्भर था। इसके बजाय, परीक्षण सूट में प्रत्येक व्यक्तिगत परीक्षण को चलने से पहले डेटाबेस को स्वचालित रूप से एक स्वच्छ और तैयार स्थिति में रखना चाहिए। (चलने के बाद डेटाबेस को वाइप करना एक परीक्षण के लिए भी विशिष्ट है, इसलिए यह अपने डेटा को अन्य परीक्षणों में "लीक" नहीं करता है। यह सख्ती से आवश्यक नहीं है यदि प्रत्येक परीक्षण चलने से पहले डेटाबेस को साफ़ करता है, लेकिन यह एक अच्छा सुरक्षात्मक उपाय है। )

परीक्षण सूट को रेल एप्लिकेशन के परीक्षण वातावरण को भी लक्षित करना चाहिए था न कि विकास के माहौल को। विकास के माहौल में एक डेवलपर की कार्रवाइयां परीक्षण सूट के काम और इसके विपरीत नहीं होनी चाहिए।

अन्य प्रकार की समस्यात्मक निर्भरताएं

मेरी कहानी में, समस्याग्रस्त निर्भरता एक डेटाबेस था जो ठीक से साफ नहीं हो रहा था।

एक अन्य प्रकार की समस्याग्रस्त निर्भरता एक नेटवर्क अनुरोध है। कल्पना कीजिए कि आपके पास एक परीक्षण सूट है जो Twilio API को हिट करता है। आप मंगलवार को टेस्ट सूट चलाते हैं और यह पास हो जाता है। फिर बुधवार को आप वही परीक्षण सूट चलाते हैं और यह विफल हो जाता है। आप से अनजान, Twilio में खराबी आ रही है, और इसीलिए आपका परीक्षण सूट विफल हो गया है। कुछ मिनट बाद समस्या का समाधान हो जाता है और आपका परीक्षण सूट फिर से पास हो जाता है।

यह इस विचार पर वापस जाता है कि एक परीक्षण केवल एक कारण से विफल होना चाहिए, और वह यह है कि यदि आपका एप्लिकेशन कोड काम करना बंद कर देता है।

यदि आपको नेटवर्क के साथ इंटरैक्ट करने वाले कोड के लिए परीक्षण लिखने की आवश्यकता है, तो इसे करने का एक बेहतर तरीका (यदि आप रूबी/रेल का उपयोग कर रहे हैं) वीसीआर जैसे टूल का उपयोग करना है जो आपको नेटवर्क अनुरोधों को रिकॉर्ड करने देता है और फिर उन्हें वास्तव में बिना फिर से चलाता है इंटरनेट का उपयोग करना।

मामले जब बाहरी निर्भरता ठीक होती है

यह तर्क दिया जा सकता है कि यदि कोई एप्लिकेशन ट्विलियो एपीआई पर निर्भर करता है और ट्विलियो एपीआई नीचे चला गया है, तो एप्लिकेशन वास्तव में टूट गया है और इसलिए परीक्षण वास्तव में विफल होना चाहिए। हम इस विचार को इस विचार के साथ कैसे मिला सकते हैं कि परीक्षण बाहरी परिस्थितियों पर निर्भर नहीं होने चाहिए?

इन दोनों चीजों के बीच सामंजस्य स्थापित करने का तरीका एकीकरण परीक्षण . के बीच अंतर करना है , जो एक साथ कई परतों या प्रणालियों का परीक्षण करते हैं, और इकाई परीक्षण , जो अलग-अलग कार्यक्षमता के एक टुकड़े का परीक्षण करता है।

यदि एक टीम को एक सचेत निर्णय लेना था कि उनके परीक्षणों का एक निश्चित सेट नेटवर्क पर बाहरी सेवाओं को प्रभावित करने वाला था, तो कई प्रणालियों का एक साथ परीक्षण किया जा सकता है, तो इसमें कुछ भी "गलत" नहीं है। (विकल्प यह होगा कि उन प्रणालियों को एक साथ परीक्षण करने का प्रयास न करने का निर्णय लिया जाए।) इस परिदृश्य में टीम को केवल यह पता होना चाहिए कि उनके नेटवर्क-निर्भर एकीकरण परीक्षण सूट की नियतात्मक होने की गारंटी नहीं है और शायद कभी-कभी बाहर निकल जाएगा . इस तरह के एक परीक्षण सूट को उन परीक्षणों के सेट से अलग रहना चाहिए जो डेवलपर्स अपनी मशीनों पर प्रतिगमन की जांच के लिए हर दिन चलाते हैं।

हालांकि इस नियम का अपवाद है कि परीक्षण बाहरी परिस्थितियों पर निर्भर नहीं होने चाहिए, अधिकांश समय नियम का पालन किया जाना चाहिए, जिससे आपके परीक्षण सूट को नियतात्मक और विश्वसनीय होने का लाभ मिलता है।


  1. उत्पादन में RubyGems.org का उपयोग करने के विरुद्ध मामला

    एक पेंच + एक स्क्रीनकास्ट आपको दिखा रहा है कि आप अपने खुद के रत्नों को कैसे होस्ट कर सकते हैं आइए इसे इस तरह से हटा दें:रत्न कमाल के हैं, और RubyGems.org एक बेहतरीन सेवा है। ...लेकिन हाल ही में जब भी मैं किसी ऐप में कोई नया रत्न जोड़ता हूं तो मुझे बेचैनी महसूस होती है। जितना अधिक मैं इसके बारे में

  1. अपने परीक्षण सूट को बेहतर बनाने के लिए वीसीआर रत्न का उपयोग कैसे करें

    यदि आपका रूबी एप्लिकेशन किसी भी प्रकार के बाहरी एपीआई का उपयोग करता है, तो संभवतः आपको धीमे परीक्षण और API दर सीमा की समस्या का सामना करना पड़ा होगा। । समाधान क्या है? आप अपनी क्लाइंट लाइब्रेरी से HTTP विधियों को मैन्युअल रूप से स्टब कर सकते हैं, और कुछ पूर्व-निर्धारित प्रतिक्रियाएँ लौटा सकते हैं।

  1. रूबी केस स्टेटमेंट के कई उपयोग

    जब भी आपको कुछ if / elsif . का उपयोग करने की आवश्यकता हो आप इसके बजाय रूबी केस स्टेटमेंट का उपयोग करने पर विचार कर सकते हैं। इस पोस्ट में, आप कुछ अलग उपयोग के मामलों के बारे में जानेंगे और यह सब वास्तव में हुड के तहत कैसे काम करता है। नोट:अन्य प्रोग्रामिंग भाषाओं में इसे स्विच . के रूप में जाना