यह निर्धारित करना कि एक उपयोगी इकाई परीक्षण क्या है


46

मैं phpunit के डॉक्स से गुज़र रहा हूं और निम्नलिखित उद्धरण के लिए आया हूं:

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

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

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

उस का महत्वपूर्ण खंड है

* और अपने स्वयं के प्रत्येक परीक्षण को अपने स्वयं के परीक्षण विधि (1-1 रिश्ते में) के साथ करने का विचार हँसी से भरा होगा। *

इसलिए यदि प्रत्येक विधि के लिए एक परीक्षण बनाना 'हंसी' है, तो आपने कैसे / कब चुना क्या आप के लिए परीक्षण लिखते हैं?


5
यह एक अच्छा सवाल है, लेकिन मुझे लगता है कि यह एक प्रोग्रामिंग लैंग्वेज स्वतंत्र प्रश्न है - आपने इसे php क्यों टैग किया?

यहाँ कुछ वास्तव में अच्छे लेख हैं जो मुझे एक अच्छी दिशा प्रदान करते हैं कि मुझे किस इकाई परीक्षण पर लिखना चाहिए और किन क्षेत्रों के लिए स्वचालित परीक्षण प्रदान करना महत्वपूर्ण है। - blog.stevensanderson.com/2009/11/04/... - blog.stevensanderson.com/2009/08/24/... - ayende.com/blog/4218/scenario-driven-tests
केन

जवाबों:


26

प्रति विधि कितने परीक्षण?

वैसे सैद्धांतिक और अत्यधिक अव्यवहारिक अधिकतम एन-पथ जटिलता है (मान लें कि परीक्षण सभी कोड के माध्यम से अलग-अलग तरीके से कवर करते हैं;))। न्यूनतम एक है !. सार्वजनिक विधि के अनुसार , वह कार्यान्वयन विवरणों का परीक्षण नहीं करता है, केवल एक वर्ग के बाहरी व्यवहार (मूल्यों को वापस करना और अन्य वस्तुओं को कॉल करना)।

आप बोली:

* और अपने स्वयं के प्रत्येक परीक्षण को अपनी स्वयं की परीक्षण विधि (1-1 रिश्ते में) के साथ करने का विचार हँसने योग्य होगा। *

और फिर पूछें:

इसलिए यदि प्रत्येक विधि के लिए एक परीक्षण बनाना 'हंसी' है, तो आपने कैसे / कब चुना क्या आप के लिए परीक्षण लिखते हैं?

लेकिन मुझे लगता है कि आप यहाँ लेखक को गलत समझ रहे हैं:

one test methodप्रति होने के विचार one method in the class to testको लेखक "हंसने योग्य" कहता है।

(मेरे लिए कम से कम) यह 'कम' के बारे में नहीं है यह 'अधिक' के बारे में है

तो मुझे फिर से समझने की तरह मैं उसे समझ गया:

और केवल एक विधि (1-1 संबंध में अपनी खुद की परीक्षा विधि) के साथ अपने प्रत्येक तरीकों का परीक्षण करने का विचार हँसने योग्य होगा।

अपना उद्धरण फिर से देने के लिए:

जब आप महसूस करते हैं कि यह व्यवहार को निर्दिष्ट करने और परीक्षण नहीं लिखने के बारे में है, तो आपका दृष्टिकोण बदल जाता है।


जब आप टीडीडी का अभ्यास करते हैं तो आपको नहीं लगता :

मेरे पास एक विधि है calculateX($a, $b);और इसे एक परीक्षण की आवश्यकता है testCalculcateXजो विधि के बारे में हर किसी का परीक्षण करे ।

TDD आपको जो बताता है वह सोचने के लिए है कि आपका कोड क्या पसंद है:

मुझे दो मानों के पहले ( पहले परीक्षण के मामले में ) की गणना करने की आवश्यकता है, लेकिन यदि $ a शून्य से छोटा है, तो उसे एक त्रुटि ( दूसरा परीक्षण मामला! ) उत्पन्न करना चाहिए और यदि $ b शून्य से छोटा है तो यह चाहिए .... ( तीसरा परीक्षण मामला! ) इत्यादि।


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

इस तरह से आपको एक परीक्षण सूट मिलता है जो आपके कोड के लिए प्रलेखन है और वास्तव में यह बताता है कि यह क्या करने की उम्मीद है, शायद इसलिए भी :)


आप अपने कोड के किस टुकड़े के लिए इकाई परीक्षण बनाते हैं, यह तय करने के बारे में आप क्या करेंगे?

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

यदि आपके पास इसके लिए कोई परीक्षण नहीं है, तो कोड बदलने के लिए यह अधिक कठिन (अधिक महंगा) हो जाता है, खासकर यदि यह परिवर्तन नहीं कर रहा है।

टीडीडी यह सुनिश्चित करने का एक तरीका है कि आपके पास हर बार परीक्षण हो लेकिन जब तक आप उन परीक्षणों को ठीक न कर लें, यह ठीक है। आमतौर पर उन्हें उसी दिन लिखना तब से मदद करता है जब आप इसे बाद में नहीं करने जा रहे हैं, क्या आप हैं? :)



टिप्पणियों का जवाब:

विधियों की एक सभ्य मात्रा को एक विशेष संदर्भ में परीक्षण नहीं किया जा सकता है क्योंकि वे या तो अन्य तरीकों पर निर्भर हैं या निर्भर हैं

खैर वहाँ तीन चीजें हैं जो उन तरीकों को कॉल कर सकते हैं:

अन्य वर्गों के सार्वजनिक तरीके

हम अन्य वर्गों का मजाक उड़ा सकते हैं इसलिए हमने वहां राज्य को परिभाषित किया है। हम संदर्भ के नियंत्रण में हैं इसलिए वहाँ कोई समस्या नहीं है।

* एक ही पर संरक्षित या निजी तरीके *

कुछ भी जो किसी वर्ग के सार्वजनिक एपीआई का हिस्सा नहीं है, सीधे परीक्षण नहीं किया जाता है, आमतौर पर।

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

एक ही वर्ग पर सार्वजनिक तरीके

ऐसा बहुत बार नहीं होता है? और अगर यह निम्न उदाहरण में पसंद करता है तो इसे संभालने के कुछ तरीके हैं:

$stuff = new Stuff();
$stuff->setBla(12);
$stuff->setFoo(14);
$stuff->execute(); 

यह बसने वाले मौजूद हैं और निष्पादित विधि का हिस्सा नहीं हैं हस्ताक्षर एक और विषय है;)

अगर हम गलत मान सेट करते हैं, तो जब हम निष्पादित करते हैं, तो हम यहां परीक्षण कर सकते हैं। यही कारण है कि setBlaएक अपवाद फेंकता है जब आप पारित एक स्ट्रिंग अलग से परीक्षण किया जा सकता है, लेकिन हम परीक्षण करना चाहते हैं, जो उन दो अनुमति प्राप्त मान (12 और 14) thats एक टेस्ट केस से (जो भी कारण के लिए) एक साथ काम नहीं है।

यदि आप "अच्छा" टेस्ट सूट चाहते हैं, तो आप php में, हो सकता है (!) @covers Stuff::executeयह सुनिश्चित करने के लिए एक एनोटेशन जोड़ें कि आप केवल इस विधि के लिए कोड कवरेज उत्पन्न करते हैं और अन्य सामान जो कि सेटअप के लिए अलग से परीक्षण किए जाने की आवश्यकता है (फिर, यदि आप चाहते हैं कि)।

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


* नोट: सवाल एसओ से माइग्रेट किया गया था और शुरू में PHP / PHPUnit के बारे में था, यही कारण है कि नमूना कोड और संदर्भ php दुनिया से हैं, मुझे लगता है कि यह अन्य भाषाओं पर भी लागू होता है क्योंकि phpunit अन्य xnnit से बहुत अलग नहीं है परीक्षण ढांचे।


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

@ robinsonc494 मैं एक उदाहरण में संपादित करता हूँ जो शायद थोड़ा बेहतर बताता है कि मैं इस के साथ कहाँ जा रहा हूँ
एडोरियन

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

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

3
मुझे लगता है कि मैंने सबसे अच्छा उदाहरण टीडीडी को देखा, जिसने वास्तव में यह क्लिक करने में मदद की कि परीक्षण के मामले कैसे लिखे जाएं, अंकल बॉब मार्टिन द्वारा बॉलिंग गेम काटा। slideshare.net/lalitkale/bowling-game-kata-by-robert-c-martin
एमी Anuszewski

2

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

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

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

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

आपके स्पष्ट प्रश्न का उत्तर देने के लिए: सार्वजनिक इंटरफ़ेस के लिए यूनिट टेस्ट का मूल्य है।

प्रतिक्रिया टिप्पणी में संपादित:

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


तो बस यह सुनिश्चित करने के लिए कि मैं समझ रहा हूं कि आप क्या कह रहे हैं: परीक्षण करते समय, सार्वजनिक इंटरफ़ेस का सही परीक्षण करने पर ध्यान दें? यह मानते हुए कि सही है ... निजी तरीकों / इंटरफेस में बग को छोड़ने की कोई बड़ी संभावना नहीं है, जिसके लिए आपने यूनिट परीक्षण नहीं किया था, कुछ "बिना" निजी "इंटरफ़ेस के कुछ पेचीदा कीड़े संभवतः टेस्ट पास करने के लिए ले जा सकते हैं। वास्तव में विफल होना चाहिए। क्या मैं ऐसा सोचने में गलत हूँ?
zcourts

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

2

यूनिट परीक्षण एक बड़ी परीक्षण रणनीति का हिस्सा होना चाहिए। लिखने के लिए और कब किस प्रकार के परीक्षण चुनने में मैं इन सिद्धांतों का पालन करता हूं:

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

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

  • प्रतीक्षा करें जब तक कि आप जिस एपीआई के खिलाफ परीक्षण कर रहे हैं, वह या तो परीक्षण के प्रकार को लिखने के लिए स्थिर है। आप अपने कार्यान्वयन और परीक्षण दोनों को फिर से बनाने से बचना चाहते हैं।

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


+1 - मैं जरूरी नहीं कि आपके सभी बिंदुओं (या लेख के अंक) से सहमत हो, लेकिन जहां मैं सहमत हूं कि ज्यादातर यूनिट परीक्षण बेकार हैं अगर आँख बंद करके (TDD दृष्टिकोण) किया जाता है। हालांकि, वे अत्यंत मूल्यवान हैं यदि आप यह तय करने में होशियार हैं कि यूनिट परीक्षण करने में समय बिताने के लायक क्या है। मैं इस बात से पूरी तरह सहमत हूं कि आप उच्च स्तरीय परीक्षणों को लिखने में हिरन के लिए कहीं अधिक धमाकेदार हैं, विशेष रूप से सबसिस्टम स्तर के स्वचालित परीक्षण में। एंड-टू-एंड स्वचालित परीक्षणों के साथ समस्या यह है कि वे कठिन होंगे, अगर पूरी तरह से अव्यवहारिक नहीं, एक प्रणाली के लिए यदि इसका कोई आकार / जटिलता है।
डंक

0

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

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

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