जब आप नकली वस्तुओं का उपयोग करते हैं तो आप यूनिट परीक्षणों के साथ निर्भरता की समस्याओं का पता कैसे लगाते हैं?


98

आपके पास एक कक्षा X है और आप कुछ इकाई परीक्षण लिखते हैं जो व्यवहार X1 को सत्यापित करते हैं। वहाँ भी ए श्रेणी है जो एक्स को एक निर्भरता के रूप में लेता है।

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

लेकिन ए के साथ क्या? ए के लिए यूनिट परीक्षण तब विफल नहीं होंगे जब एक्स के व्यवहार को संशोधित किया जाता है (एक्स के मजाक के कारण)। कैसे पता लगाएं कि "वास्तविक" (संशोधित) एक्स के साथ चलने पर ए का परिणाम अलग होगा?

मुझे लाइन के साथ उत्तर की उम्मीद है: "यह इकाई परीक्षण का उद्देश्य नहीं है", लेकिन इकाई परीक्षण का क्या मूल्य है? क्या यह वास्तव में केवल आपको बताता है कि जब सभी परीक्षण पास हो जाते हैं, तो आपने एक परिवर्तन नहीं किया है? और जब कुछ वर्ग का व्यवहार बदलता है (स्वेच्छा से या अनिच्छा से), तो आप कैसे पता लगा सकते हैं (अधिमानतः स्वचालित तरीके से) सभी परिणाम? क्या हमें एकीकरण परीक्षण पर अधिक ध्यान नहीं देना चाहिए?



36
सुझाए गए सभी उत्तरों के अलावा, मुझे कहना होगा कि मैं निम्नलिखित कथन के साथ मुद्दा ले सकता हूं: 'क्या यह वास्तव में केवल आपको बताता है कि जब सभी परीक्षण पास हो जाते हैं, तो आपने एक ब्रेकिंग परिवर्तन नहीं पेश किया है?' यदि आप वास्तव में सोचते हैं कि रिफैक्टरिंग के डर को दूर करना बहुत कम मूल्य है, तो आप
अचूक

5
यूनिट टेस्टिंग आपको बताती है कि क्या आपके कोड ऑफ यूनिट ने जैसा आप उम्मीद करते हैं वैसा ही व्यवहार किया है। कम या ज्यादा नहीं। मोक्स और टेस्ट डबल्स आपके यूनिट कोड (अलगाव में) को देखने के लिए एक कृत्रिम, नियंत्रित वातावरण प्रदान करते हैं यह देखने के लिए कि क्या यह आपकी अपेक्षाओं को पूरा करता है। कम या ज्यादा नहीं।
रॉबर्ट हार्वे

2
मेरा मानना ​​है कि आपका आधार गलत है। जब आप उल्लेख X1करते हैं कि आप Xइंटरफ़ेस लागू कर रहे हैं X1। यदि आप इंटरफ़ेस X1को X2मॉक में बदलते हैं तो आपको अन्य परीक्षणों में उपयोग नहीं करना चाहिए, इसलिए आपको उन परीक्षणों को भी ठीक करने के लिए मजबूर होना चाहिए। वर्ग के व्यवहार में बदलाव मायने नहीं रखना चाहिए। वास्तव में, आपकी कक्षा Aको कार्यान्वयन विवरण (जो आप उस स्थिति में बदल रहे हैं) पर निर्भर नहीं होना चाहिए। इसलिए इकाई परीक्षण Aअभी भी सही हैं, और वे आपको बताते हैं कि Aइंटरफ़ेस के एक आदर्श कार्यान्वयन को देखते हुए काम करता है।
बकुरीउ

5
मैं आपके बारे में नहीं जानता, लेकिन जब मुझे बिना किसी परीक्षण के एक कोडबेस पर काम करना होता है, तो मुझे डर लगता है कि मैं कुछ तोड़ दूंगा। और क्यों? क्योंकि ऐसा बहुत बार होता है कि कुछ तब टूटता है जब इसका कोई इरादा नहीं था। और हमारे परीक्षक के दिलों को आशीर्वाद दें, वे हर चीज का परीक्षण नहीं कर सकते। या पास भी। लेकिन एक इकाई परीक्षण खुशी से उबाऊ दिनचर्या के बाद उबाऊ दिनचर्या से दूर हो जाएगा।
corsiKa

जवाबों:


125

जब आप A के लिए इकाई परीक्षण लिखते हैं, तो आप X का मज़ाक उड़ाते हैं

क्या आप? मैं नहीं, जब तक मैं पूरी तरह से नहीं है। मुझे अगर:

  1. X धीमा है, या
  2. X साइड इफेक्ट है

यदि इनमें से कोई भी लागू नहीं होता है, तो मेरी इकाई परीक्षण भी Aपरीक्षण करेगी X। कुछ भी कर एक अतार्किक चरम सीमा तक अलग-थलग परीक्षण कर रहा होगा।

यदि आपके पास आपके कोड के अन्य भागों के नकली का उपयोग करके आपके कोड के कुछ हिस्से हैं, तो मैं सहमत हूँ: ऐसी इकाई परीक्षणों का क्या मतलब है? तो यह मत करो। उन परीक्षणों को वास्तविक निर्भरता का उपयोग करने दें क्योंकि वे उस तरह से अधिक मूल्यवान परीक्षण बनाते हैं।

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


94
@Laiv, नहीं, इकाई परीक्षणों को एक इकाई के रूप में माना जाता है, अर्थात अन्य परीक्षणों से अलगाव में चलाया जाता है । नोड्स और ग्राफ में बढ़ोतरी हो सकती है। अगर मैं थोड़े समय में एक पृथक, साइड-इफेक्ट फ्री एंड-टू-एंड टेस्ट चला सकता हूं, तो यह एक यूनिट टेस्ट है। यदि आपको वह परिभाषा पसंद नहीं है, तो इसे एक स्वचालित परीक्षण कहें और मूर्खतापूर्ण शब्दार्थों को फिट करने के लिए बकवास परीक्षण लिखना बंद करें।
डेविड अरनो

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

13
आप प्रश्न का उत्तर देने के बजाय एक अलग तरह के परीक्षण की वकालत कर रहे हैं। जो एक मान्य बिंदु है, लेकिन यह इसे करने का एक बहुत अच्छा तरीका है।
फिल फ्रॉस्ट

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

30
मैं इस पर @DavidArno के साथ हूं; : मेरे परीक्षण रणनीति इयान कूपर ने इस बात को देखने के बाद बदल vimeo.com/68375232 । इसे एक वाक्य में उबालने के लिए: कक्षाओं का परीक्षण न करें । परीक्षण व्यवहार । आपके परीक्षणों में वांछित व्यवहार को लागू करने के लिए उपयोग किए जाने वाले आंतरिक वर्गों / विधियों का ज्ञान नहीं होना चाहिए; उन्हें केवल आपके API / लाइब्रेरी की सार्वजनिक सतह का पता होना चाहिए और उन्हें इसका परीक्षण करना चाहिए। यदि परीक्षणों में बहुत अधिक ज्ञान है, तो आप कार्यान्वयन विवरणों का परीक्षण कर रहे हैं और आपके परीक्षण भंगुर हो जाते हैं, आपके कार्यान्वयन के लिए युग्मित हो जाते हैं, और वास्तव में आपकी गर्दन के चारों ओर एक लंगर होता है।
रिचीबन

79

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

मान लीजिए कि आपके पास क्लास ए है, जिसमें सभी रास्तों को पूरी तरह से कवर करने के लिए 10 यूनिट टेस्ट की आवश्यकता होती है। फिर आपके पास एक और वर्ग बी है, जिसमें कोड के माध्यम से ले जाने वाले सभी रास्तों को कवर करने के लिए 10 इकाई परीक्षणों की भी आवश्यकता होती है। अब हम अपने आवेदन में कहते हैं, आपको A के आउटपुट को B में फीड करना होगा। अब आपका कोड A के इनपुट से B के आउटपुट तक 100 अलग-अलग रास्ते ले सकता है।

यूनिट परीक्षणों के साथ, आपको सभी मामलों को पूरी तरह से कवर करने के लिए केवल 20 यूनिट परीक्षण + 1 एकीकरण परीक्षण की आवश्यकता होती है।

एकीकरण परीक्षणों के साथ, आपको सभी कोड रास्तों को कवर करने के लिए 100 परीक्षणों की आवश्यकता होगी।

एकीकरण परीक्षणों पर निर्भर रहने के डाउनसाइड्स के बारे में यहां एक बहुत अच्छा वीडियो है केवल जेबी रेन्सबर्गर इंटीग्रेटेड टेस्ट्स ए स्कैम एचडी


1
मुझे यकीन है कि यह कोई संयोग नहीं है कि एकीकरण परीक्षणों की प्रभावकारिता पर सवालिया निशान हर अधिक परतों को कवर करने वाली इकाई परीक्षणों के साथ हाथ से चला गया है।
रॉबी डी

16
ठीक है, लेकिन कहीं भी आपके 20 यूनिट टेस्ट के लिए मॉकिंग की आवश्यकता नहीं है। यदि आपके पास A के अपने 10 परीक्षण हैं जो सभी A को कवर करते हैं और आपके 10 परीक्षण जो B के सभी को कवर करते हैं और 25% A को एक बोनस के रूप में पुन: प्राप्त करते हैं, तो यह "ठीक" और एक अच्छी बात है। Bs परीक्षणों में Mocking A सक्रिय रूप से बेवकूफ लगता है (जब तक कि वास्तव में कोई कारण नहीं है कि A कोई समस्या क्यों है, उदाहरण के लिए यह डेटाबेस है या यह अन्य चीजों की एक लंबी वेब में लाता है)
रिचर्ड टिंगल

9
मैं इस विचार से असहमत हूं कि यदि आप पूर्ण कवरेज चाहते हैं तो एकल एकीकरण परीक्षण पर्याप्त है। ए क्या आउटपुट के आधार पर अलग-अलग होगा, इसके लिए बी की प्रतिक्रियाएं; यदि A में कोई पैरामीटर बदल रहा है तो इसका आउटपुट बदल जाता है, तो B इसे सही तरीके से नहीं संभाल सकता है।
मैथ्यू एम।

3
@ Eternal21: मेरा कहना था कि कभी-कभी, समस्या व्यक्तिगत व्यवहार में नहीं होती है, बल्कि एक अप्रत्याशित बातचीत में होती है। यही है, जब ए और बी के बीच का गोंद अप्रत्याशित रूप से कुछ परिदृश्य में व्यवहार करता है। तो ए और बी दोनों विनिर्देशों के अनुसार कार्य करते हैं, और खुश मामला काम करता है, लेकिन कुछ इनपुट पर गोंद कोड में एक बग होता है ...
मैथ्यू एम।

1
@MatthieuM। मेरा तर्क है कि यह यूनिट परीक्षण के दायरे से परे है। ग्लू कोड का परीक्षण इकाई के रूप में किया जा सकता है जबकि ए और बी के बीच गोंद कोड के माध्यम से होने वाली बातचीत एक एकीकरण परीक्षण है। जब विशिष्ट किनारे के मामले या कीड़े पाए जाते हैं, तो उन्हें गोंद कोड इकाई परीक्षणों में जोड़ा जा सकता है और अंततः एकीकरण परीक्षण में सत्यापित किया जा सकता है।
एंड्रयू टी फिनेल

72

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

वाह, एक पल रुकिए। एक्स फेलिंग के लिए परीक्षणों के निहितार्थ इस तरह से चमकने के लिए बहुत महत्वपूर्ण हैं।

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

X2, Liskov अर्थ में एक X नहीं है , इसलिए आपको अपने हितधारकों की जरूरतों को पूरा करने के अन्य तरीकों के बारे में सोचना चाहिए (जैसे कि एक नया विनिर्देशन Y शुरू करना, जो कि X2 द्वारा लागू किया गया है)।

गहरी अंतर्दृष्टि के लिए, पीटर हिंजेंस: सॉफ़्टवेयर संस्करणों का अंत या रिच हिक्की सिंपल मेड ईज़ी देखें

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

एकीकृत परीक्षण की समीक्षा एक घोटाला है ; उच्च स्तर में, आपसे अपेक्षा की जाती है कि आपके पास उतने ही अलग-थलग परीक्षण हों जितने कि X2 अनुबंध X को सही ढंग से लागू करने की आवश्यकता है, और उतने ही अलग-थलग किए गए परीक्षणों से आपको यह सुनिश्चित करने की आवश्यकता है कि A एक X से सही प्रतिक्रिया देता है, और कुछ छोटी संख्या में एकीकृत परीक्षण यह सुनिश्चित करने के लिए कि एक्स 2 और ए क्या एक्स का मतलब पर सहमत हैं।

आप कभी-कभी इस अंतर को एकान्त परीक्षणों बनाम sociableपरीक्षणों के रूप में व्यक्त करते देखेंगे ; यूनिट टेस्ट के साथ प्रभावी रूप से काम करने वाले जे फील्ड्स देखें ।

क्या हमें एकीकरण परीक्षण पर अधिक ध्यान नहीं देना चाहिए?

फिर से, देखें कि एकीकृत परीक्षण एक घोटाला है - रैंसेबर्गर एक सकारात्मक फीडबैक लूप का विस्तार से वर्णन करता है जो एकीकृत (नोट वर्तनी) परीक्षणों पर भरोसा करने वाली परियोजनाओं के लिए आम है (अपने अनुभवों में)। संक्षेप में, डिजाइन पर दबाव डालने वाले पृथक / एकान्त परीक्षणों के बिना , गुणवत्ता में गिरावट आती है, जिससे अधिक गलतियाँ और अधिक एकीकृत परीक्षण होते हैं ...।

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


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

1
"डिजाइन के लिए दबाव लागू करने वाले पृथक / एकान्त परीक्षणों के बिना, गुणवत्ता में गिरावट"। मुझे लगता है कि यह एक महत्वपूर्ण बिंदु है। व्यवहार की जांच के साथ, यूनिट-परीक्षणों का साइड इफेक्ट है जो आपको अधिक मॉड्यूलर डिजाइन करने के लिए मजबूर करता है।
मिकाल्ग

मुझे लगता है कि यह सब सच है, लेकिन यह कैसे मेरी मदद करता है अगर एक बाहरी निर्भरता अनुबंध एक्स के लिए एक असंगत परिवर्तन का परिचय देती है? शायद लाइब्रेरी में I / O-Perform करने वाली क्लास संगतता को तोड़ती है, और हम X का मज़ाक उड़ा रहे हैं क्योंकि हम CI में यूनिट टेस्ट नहीं चाहते हैं ताकि I / O पर निर्भर रहें। मुझे लगता है कि ओपी इसके लिए परीक्षण करने के लिए कह रहा है, और मुझे समझ नहीं आ रहा है कि यह सवाल का जवाब कैसे देता है। इसके लिए टेस्ट कैसे करें?
gerrit

15

मुझे यह कहने से शुरू करना चाहिए कि प्रश्न का मूल आधार त्रुटिपूर्ण है।

आप कभी भी परीक्षण (या मॉकिंग) कार्यान्वयन नहीं कर रहे हैं, आप परीक्षण (और मॉकिंग) इंटरफेस कर रहे हैं ।

अगर मेरे पास एक वास्तविक दसवीं कक्षा है जो इंटरफ़ेस X1 को लागू करता है, तो मैं एक मॉक एक्सएम लिख सकता हूं जो एक्स 1 का अनुपालन भी करता है। तब मेरी कक्षा ए को एक्स 1 को लागू करने वाली किसी चीज का उपयोग करना चाहिए, जो या तो एक्स एक्स या मॉक एक्सएम हो सकता है।

अब, मान लीजिए कि हम X को एक नया इंटरफ़ेस X2 लागू करने के लिए बदलते हैं। खैर, जाहिर है मेरा कोड अब संकलित नहीं है। A को कुछ ऐसी चीज़ों की आवश्यकता होती है जो X1 को लागू करती है, और जो अब मौजूद नहीं है। मुद्दे की पहचान कर ली गई है और इसे ठीक किया जा सकता है।

मान लीजिए कि X1 की जगह, हम इसे संशोधित करते हैं। अब कक्षा ए पूरी तरह तैयार है। हालाँकि, मॉक एक्सएम अब इंटरफ़ेस X1 को लागू नहीं करता है। मुद्दे की पहचान कर ली गई है और इसे ठीक किया जा सकता है।


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

यह तब टूट जाता है जब आपके तरीकों के दुष्प्रभाव होते हैं, लेकिन मुझे लगता है कि इसे सुरक्षित रूप से बाहर रखा जा सकता है क्योंकि "यूनिट परीक्षण या मॉकडाउन नहीं किया जा सकता है"।


11
यह उत्तर बहुत सारी धारणाएँ बनाता है जिनकी आवश्यकता नहीं है। सबसे पहले, यह मानता है, मोटे तौर पर, कि हम C # या जावा में हैं (या, अधिक सटीक रूप से, कि हम संकलित भाषा में हैं, कि भाषा में इंटरफेस है, और वह X एक इंटरफ़ेस लागू करता है; इनमें से कोई भी सत्य नहीं है)। दूसरे, यह मानता है कि एक्स के व्यवहार या "अनुबंध" में किसी भी परिवर्तन के लिए इंटरफ़ेस में बदलाव की आवश्यकता होती है (जैसा कि संकलक द्वारा समझा जाता है) कि एक्स लागू होता है। यह स्पष्ट रूप से है नहीं सच है, भले ही हम कर रहे हैं में जावा या सी #; आप इसके हस्ताक्षर को बदले बिना एक विधि कार्यान्वयन को बदल सकते हैं।
मार्क अमेरी

6
@MarkAmery यह सच है कि "इंटरफ़ेस" शब्दावली C # या Java के लिए अधिक विशिष्ट है, लेकिन मुझे लगता है कि बिंदु व्यवहार के एक परिभाषित "अनुबंध" को मानती है (और यदि इसे संहिताबद्ध नहीं किया गया है तो स्वचालित रूप से यह पता लगाना असंभव है)। आप यह भी पूरी तरह सही हैं कि अनुबंध में बदलाव के बिना कार्यान्वयन को बदला जा सकता है। लेकिन इंटरफ़ेस में बदलाव (या अनुबंध) के बिना कार्यान्वयन में बदलाव किसी भी उपभोक्ता को प्रभावित नहीं करना चाहिए। यदि ए का व्यवहार इस बात पर निर्भर करता है कि इंटरफ़ेस (या अनुबंध) कैसे लागू किया जाता है, तो यह (सार्थक) इकाई परीक्षण के लिए असंभव है।
व्लादिमीर ४ Vlad

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

4
@ मार्की: मुझे नहीं लगता कि व्लाद "इंटरफ़ेस" शब्द का उपयोग उसी अर्थ में कर रहे हैं जैसे आप इसका उपयोग कर रहे हैं; जिस तरह से मैं उत्तर पढ़ता हूं, वह संकीर्ण सी # / जावा अर्थ (अर्थात विधि हस्ताक्षर का एक सेट) में इंटरफेस के बारे में बात नहीं कर रहा है, लेकिन शब्द के सामान्य अर्थ में, उदाहरण के लिए "एप्लिकेशन प्रोग्रामिंग इंटरफ़ेस" या यहां तक ​​कि " प्रयोक्ता इंटरफ़ेस"। [...]
इल्मरी करोनें

6
@ इल्मारियारोनन अगर व्लाद संकीर्ण सी # / जावा अर्थ में "अनुबंध" का अर्थ "इंटरफ़ेस" का उपयोग कर रहा है, तो कथन "अब, मान लीजिए कि हम एक नया इंटरफ़ेस एक्स 2 को लागू करने के लिए एक्स को बदलते हैं। ठीक है, जाहिर है कि मेरा कोड अब लंबा संकलन करता है। " केवल सादा झूठ है, क्योंकि आप किसी भी विधि हस्ताक्षर को बदलने के बिना एक अनुबंध को बदल सकते हैं। लेकिन ईमानदारी से, मुझे लगता है कि समस्या यह है कि व्लाद या तो लगातार अर्थ का उपयोग नहीं कर रहा है, लेकिन उन्हें भ्रमित कर रहा है - जो कि यह दावा करने के मार्ग को नीचे ले जाता है कि अनुबंध एक्स 1 में कोई भी बदलाव जरूरी है कि यह गलत है कि ध्यान दिए बिना एक संकलन त्रुटि का कारण होगा। ।
मार्क अमेरी

9

अपने प्रश्नों को बदले में लेना:

इकाई परीक्षण के बाद क्या मूल्य होता है

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

क्या यह वास्तव में केवल आपको बताता है कि जब सभी परीक्षण पास हो जाते हैं, तो आपने एक परिवर्तन नहीं किया है

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

और जब कुछ वर्ग का व्यवहार बदलता है (स्वेच्छा से या अनिच्छा से), तो आप कैसे पता लगा सकते हैं (अधिमानतः स्वचालित तरीके से) सभी परिणाम

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

क्या हमें एकीकरण परीक्षण पर अधिक ध्यान नहीं देना चाहिए?

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

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

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


9

यह सही है।

यूनिट परीक्षण एक यूनिट की पृथक कार्यक्षमता का परीक्षण करने के लिए होते हैं, पहली-नज़र की जाँच करें कि यह उद्देश्य के रूप में काम करता है और इसमें बेवकूफ त्रुटियां नहीं हैं।

इकाई परीक्षण यह परीक्षण करने के लिए नहीं हैं कि संपूर्ण अनुप्रयोग काम करता है।

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

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

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

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


2

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

यदि आपके पास वास्तविक अनुबंध हैं, तो वर्ग आक्रमणकारियों, पूर्व-स्थितियों और पोस्ट स्थितियों से मिलकर, निचले स्तर के घटकों के अनुबंधों पर उच्च स्तर के घटकों की शुद्धता को आधार बनाकर, पदानुक्रम को सही साबित करना संभव है। यह अनुबंध द्वारा डिजाइन के पीछे मौलिक अवधारणा है।


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

7
@ रोबीडी मुझे लगता है, उनका मतलब था कि जब आप परीक्षण करते हैं fac(5) == 120, तो आपने यह साबित नहीं किया है कि fac()वास्तव में इसके तर्क की सच्चाई वापस आ जाती है। आपने केवल यह सिद्ध किया है कि fac()जब आप पास होते हैं, तो पांच का गुट लौटाता है 5। और यहां तक ​​कि यह भी निश्चित नहीं है, क्योंकि टिम्बकटू में कुल ग्रहण के बाद पहले सोमवार के बजाय गर्भधारण की fac()वापसी हो सकती है 42... यहाँ समस्या यह है, कि आप व्यक्तिगत परीक्षण इनपुट की जाँच करके अनुपालन साबित नहीं कर सकते हैं, आपको सभी अतिरिक्त इनपुट की जाँच करने की आवश्यकता होगी और यह भी साबित करें कि आप किसी को नहीं भूले हैं (जैसे सिस्टम घड़ी पढ़ना)।
सेमीस्टर

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

1
@cmaster आपने एक परीक्षण और एक प्रमाण के बीच अंतर को बहुत अच्छी तरह से सारांशित किया। धन्यवाद!
फ्रैंक हिलमैन

2

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

मुझे एक बेहतर रणनीति है कि आप चिंताओं को अच्छी तरह से अलग कर सकें (जैसे आप Z के माध्यम से भागों B में लाए बिना अपने ऐप के भाग A का परीक्षण कर सकते हैं)। इतनी अच्छी वास्तुकला वास्तव में अच्छी परीक्षा लिखने में मदद करती है।

इसके अलावा, मैं साइड इफेक्ट्स को स्वीकार करने के लिए तैयार हूं, जब तक कि मैं उन्हें वापस रोल कर सकता हूं, जैसे कि अगर मेरा तरीका डीबी में डेटा को संशोधित करता है, तो इसे करने दें! जब तक मैं db को पिछली स्थिति में वापस ला सकता हूं, तब तक क्या नुकसान है? इसके अलावा, लाभ यह है कि मेरा परीक्षण जांच कर सकता है कि क्या डेटा अपेक्षित है। इन-मेमोरी DBs या dbs के विशिष्ट परीक्षण-संस्करण वास्तव में यहाँ मदद करते हैं (उदाहरण के लिए रेवेनबेड्स इन-मेमोरी टेस्ट संस्करण)।

अंत में, मैं सेवा सीमाओं पर मज़ाक करना पसंद करता हूं, जैसे कि http को सेवा b में कॉल नहीं करते हैं, लेकिन चलो इसे इंटरसेप्ट करते हैं और एक एप्रीप्टिएट शुरू करते हैं


1

काश दोनों शिविरों में लोग यह समझ जाते कि क्लास टेस्टिंग और बिहेवियर टेस्टिंग ऑर्थोगोनल नहीं है।

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

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

इसके अलावा, चाहे आपके स्वचालित परीक्षण कक्षा या व्यवहार लाइनों के साथ आगे बढ़ें, बल्कि आपकी प्राथमिकताओं पर निर्भर करते हैं। कुछ को तेजी से प्रोटोटाइप की आवश्यकता होगी और कुछ को दरवाजे से बाहर निकालना होगा जबकि अन्य को घर की शैलियों के कारण कवरेज की कमी होगी। बहुत से कारण। वे दोनों पूरी तरह से मान्य दृष्टिकोण हैं। आप अपने पैसे का भुगतान करते हैं, आप अपनी पसंद लेते हैं।

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

हालाँकि, एक नए व्यवहार को शुरू करने के लिए सिस्टम से समझौता करने की आवश्यकता नहीं है। लिनक्स एट अल डिप्रेक्टेड फीचर्स से भरपूर हैं। और बदलने के लिए सभी कॉलिंग कोड को मजबूर किए बिना कंस्ट्रक्टर (और तरीके) जैसी चीजें खुशी से ओवरलोड हो सकती हैं।

जहाँ कक्षा परीक्षण की जीत होती है, वहाँ आपको एक ऐसे वर्ग में बदलाव करने की आवश्यकता होती है जो अभी तक (समय की कमी, जटिलता या जो भी हो) के कारण अभी तक गिर नहीं गया है। यदि यह व्यापक परीक्षण है तो एक कक्षा के साथ आरंभ करना इतना आसान है।


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

0

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

जब आप ए के लिए यूनिट परीक्षण लिखते हैं, तो आप एक्स का मजाक उड़ाते हैं। दूसरे शब्दों में, यूनिट परीक्षण ए के दौरान, आप एक्स के नकली होने के व्यवहार को एक्स 1 होने के लिए निर्धारित (स्थगित) करते हैं।

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

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

तो शायद X ने शुरुआत में सोमवार को खाली डेटा और मंगलवार को खाली सूची दी। लेकिन अब जब एक्स ने सोमवार को अनक्रेडेड डेटा लौटाया और मंगलवार को अपवाद फेंकता है, तो ए परवाह नहीं करता है - उन परिदृश्यों को पहले से ही ए के यूनिट टेस्ट में कवर किया गया था।


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

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

क्या होगा यदि मैं PHP में या जावा या जावास्क्रिप्ट में सरणियों का उपयोग कर रहा हूं, यदि आप सरणी का एक सूचकांक बदलते हैं या इसे हटाते हैं, तो उन भाषाओं में से कोई भी संकलक आपको इसके बारे में बताएगा, सूचकांक 36 वें स्थान पर नेस्टेड हो सकता है - विचार किया गया नंबर सरणी का नेस्टेड स्तर, इसलिए मुझे लगता है कि संकलक इसके लिए समाधान नहीं है।
फनटोमएक्स 1

-2

आपको विभिन्न परीक्षणों को देखना होगा।

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

को वास्तव में अपनी इकाई परीक्षणों के लिए एक्स का मजाक करना चाहिए और मॉक के साथ परीक्षण आपको इसे बदलने के बाद भी गुजरता रहना चाहिए।

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

इसके अलावा यदि X को एक नया व्यवहार करने की आवश्यकता है, तो एक नई विधि की आपूर्ति करना बेहतर होगा जो वांछित परिणाम की आपूर्ति करेगा

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