क्या अभिकर्मक या इकाई परीक्षण अधिक महत्वपूर्ण हैं?


51

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


4
मुझे यह विचार बहुत पसंद है ... इतना कि मैं विषय को अपने सॉफ़्टवेयर परीक्षण और गुणवत्ता आश्वासन पाठ्यक्रम के लिए असाइनमेंट बना रहा हूं। :-)
मेकनेल

एक और सवाल यह है कि क्या आपको अपने दावों की जांच करनी चाहिए? ;)
मोजुबा

जवाबों:


43

कार्यक्रम की आंतरिक स्थिति के बारे में बताने के लिए दावे आपके लिए उपयोगी हैं । उदाहरण के लिए, आपकी डेटा संरचनाओं में एक मान्य स्थिति है, उदाहरण के लिए, कि एक Timeडेटा संरचना का मान नहीं होगा 25:61:61। मुखर द्वारा जाँच की जाने वाली शर्तें हैं:

  • पूर्व-शर्तें, जो यह विश्वास दिलाती हैं कि कॉलर अपना अनुबंध रखता है,

  • पोस्टकंडिशन, जो आश्वासन देते हैं कि कैली अपने अनुबंध को बनाए रखता है, और

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

मॉड्यूल के बाहरी व्यवहार के बारे में बताने के लिए इकाई परीक्षण उपयोगी होते हैं । विधि कहे Stackजाने के बाद आपके पास एक सुसंगत स्थिति हो सकती है push(), लेकिन यदि तीन बार पुकारने के बाद स्टैक का आकार तीन से नहीं बढ़ता है, तो यह एक त्रुटि है। (उदाहरण के लिए, तुच्छ मामला जहां गलत push()कार्यान्वयन केवल एसेर्ट्स की जांच करता है और बाहर निकलता है।)

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

परीक्षण किया जा रहा है में कुछ ओवरलैप हो सकता है। उदाहरण के लिए, एक Stackपोस्टकंडिशन वास्तव में यह दावा कर सकता है कि स्टैक का आकार एक से बढ़ जाता है। लेकिन उस दावे में जो किया जा सकता है, उसकी सीमाएँ हैं: क्या यह भी जाँचना चाहिए कि शीर्ष तत्व वही था जो अभी जोड़ा गया था?

दोनों के लिए, गुणवत्ता बढ़ाना लक्ष्य है। इकाई परीक्षण के लिए, लक्ष्य बग ढूंढना है। दावे के लिए, लक्ष्य जैसे ही होता है अमान्य प्रोग्राम राज्यों का अवलोकन करके डिबगिंग को आसान बनाना है।

ध्यान दें कि न तो तकनीक शुद्धता की पुष्टि करती है। वास्तव में, यदि आप कार्यक्रम को सत्यापित करने के लिए लक्ष्य के साथ इकाई परीक्षण करते हैं, तो आप संभावित रूप से निर्बाध परीक्षण के साथ आएंगे, जो आपको पता है कि काम करेगा। यह एक मनोवैज्ञानिक प्रभाव है: आप अपने लक्ष्य को पूरा करने के लिए जो कुछ भी करेंगे, वह करेंगे। यदि आपका लक्ष्य बग ढूंढना है, तो आपकी गतिविधियाँ इस बात को प्रतिबिंबित करेंगी।

दोनों महत्वपूर्ण हैं, और उनके अपने उद्देश्य हैं।

[जोर के बारे में एक अंतिम नोट के रूप में: सबसे अधिक मूल्य प्राप्त करने के लिए, आपको उन्हें अपने कार्यक्रम में सभी महत्वपूर्ण बिंदुओं पर उपयोग करने की आवश्यकता है, न कि कुछ प्रमुख कार्यों के लिए। अन्यथा, समस्या का मूल स्रोत डिबगिंग के घंटों के बिना पता लगाने में कठिन और कठिन हो सकता है।]


7

जब मुखरता के बारे में बात करते हैं, तो ध्यान रखें कि उन्हें स्विच के फ्लिक पर बंद किया जा सकता है।

एक बहुत बुरा दावा का उदाहरण:

char *c = malloc(1024);
assert(c != NULL);

यह बुरा क्यों है? क्योंकि NDEBUG परिभाषित होने जैसी किसी चीज़ के कारण उस दावे को छोड़ दिया जाए तो कोई त्रुटि जाँच नहीं की जाती है।

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

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

ऐसे कई अन्य मामले हैं जहां पर्याप्त रूप से चीजों को संभालने के बजाय दावे का उपयोग किया जाता है जो गलत हो सकते हैं। यही कारण है कि मुखरता को एक खराब प्रतिष्ठा मिलती है, और गो जैसी भाषाएं उन्हें शामिल क्यों नहीं करती हैं।

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

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


3
इसीलिए दावे हमेशा सही कथन के लिए होते हैं, त्रुटि परीक्षण के लिए नहीं।
डोमिनिक मैकडोनेल 5

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

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

@ चरण शायर, बहुत सच्चा। आप अभी भी उत्पादन में जल्द से जल्द त्रुटि राज्य में कठिन असफल होना चाहिए। सुनिश्चित करें कि उपयोगकर्ता शिकायत करने जा रहे हैं, लेकिन यह एकमात्र तरीका है जिससे आप यह सुनिश्चित करने जा रहे हैं कि बग्स ठीक होने वाले हैं। और यह पूरी तरह से बेहतर है कि ब्ला को प्राप्त करने के लिए एक स्मृति अपवाद की तुलना में 0 था जो कुछ समारोह कॉल के बाद डेरेफेरिंग के लिए एक स्मृति अपवाद था।
डोमिनिक मैकडोनेल

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

5

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

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

विचार का एक विद्यालय है जो कहता है कि यदि आप कुछ "मुखर" कर रहे हैं, तो आप एक if/ throwसार्थक अपवाद ब्लॉक लिख सकते हैं । यह विचार प्रक्रिया सभी मूल्यों को सुनिश्चित करने के लिए एक विधि की शुरुआत में रखी गई कई आवृत्तियों से आती है। अपने पूर्व शर्त का परीक्षण एक अपेक्षित पोस्टकांड होने का एक बहुत ही महत्वपूर्ण हिस्सा है।

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

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

http://en.wikipedia.org/wiki/Design_by_contract#Languages_with_native_support

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.