यदि आपकी इकाई परीक्षण कोड "बदबू आती है" तो क्या यह वास्तव में मायने रखता है?


52

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

मुझे खराब डिजाइन ("बदबूदार") यूनिट परीक्षणों पर कितना चिंतित होना चाहिए?


8
आपके द्वारा हमेशा कॉपी किए जाने वाले कोड को ठीक करना कितना कठिन हो सकता है?
जेफो

7
परीक्षणों में कोड गंध आसानी से कोड के बाकी हिस्सों में छिपी हुई गंध का एक संकेतक हो सकता है - परीक्षणों का दृष्टिकोण ऐसा क्यों मानें कि वे "वास्तविक" कोड नहीं हैं?
होरूसकॉल

जवाबों:


75

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

यहाँ कुछ सामान्य इकाई परीक्षण गंध हैं:

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

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

दूसरी ओर, यूनिट परीक्षणों के लिए कुछ अच्छे अभ्यास हैं:

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

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

3
@ Jörg सहमत थे, लेकिन क्या वास्तव में DAMP किसी चीज के लिए खड़ा है? : डी
रीन हेनरिक

5
@ रीन: वर्णनात्मक और अर्थपूर्ण वाक्यांश। इसके अलावा, पूरी तरह से DRY नहीं। देखें codeshelter.wordpress.com/2011/04/07/...
रॉबर्ट हार्वे

+1। मुझे DAMP का अर्थ भी नहीं पता था।
एगारिया

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

67

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


17
+1 जिस क्षण आप असफल परीक्षणों को अनदेखा करना शुरू करते हैं, वे कोई मूल्य नहीं जोड़ते हैं।

19

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

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


4
+1 आपको परीक्षण कोड बनाए रखना होगा, उत्पादन कोड की तरह
हमीश स्मिथ

इस विषय के बारे में एक और बहुत अच्छी पुस्तक है गेरार्ड मेस्ज़्रोस का "एक्सयूनिट टेस्ट पैटर्न - रिफैटकोरिंग टेस्ट कोड"।
एड्रिनोबिमवेज़र

7

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

निचला रेखा - इसका परीक्षण, यह आसान होने का अनुमान है। आप "बदबूदार" कोड के साथ खुद को भ्रमित नहीं करना चाहते हैं।


5
+1: यूनिट टेस्ट कोड पर उपद्रव न करें। कुछ गूंगे प्रश्न यूनिट टेस्ट कोड को और अधिक "मजबूत" बनाने के लिए घूमते हैं, ताकि एक प्रोग्रामिंग परिवर्तन यूनिट टेस्ट को तोड़ न सके। मूर्खता। यूनिट परीक्षणों को भंगुर होने के लिए डिज़ाइन किया गया है। यदि वे परीक्षण कोड के परीक्षण के लिए डिज़ाइन किए गए से कम मजबूत हैं तो यह ठीक है।
एस.लॉट

1
@ S.Lott दोनों सहमत हैं और असहमत हैं, मेरे जवाब में बेहतर तरीके से समझाया गया है।
रीन हेनरिच्स

1
@ हेन हेनरिच: वे प्रश्न में वर्णित से कहीं अधिक गंभीर बदबू आ रही है। "कॉपी और पेस्ट" और "काफी बदसूरत दिख रहे हैं" यह उतना बुरा नहीं है जितना कि आपके वर्णन में बदबू आती है जहां परीक्षण अविश्वसनीय हैं।
एस.लॉट

1
@ S.Lott बिल्कुल, मुझे लगता है कि अगर हम "यूनिट टेस्टिंग स्मेल्स" के बारे में बात करने जा रहे हैं, तो यह महत्वपूर्ण है कि यह भेद करना महत्वपूर्ण है। यूनिट परीक्षणों में कोड की गंध अक्सर नहीं होती है। वे विभिन्न उद्देश्यों के लिए लिखे गए हैं और एक संदर्भ में उन्हें बदबूदार बनाने वाले तनाव दूसरे में बहुत भिन्न हैं।
रीन हेनरिक

2
@ S.Lott यह बहुत उपेक्षित चैट सुविधा का उपयोग करने के लिए एक सही अवसर की तरह लगता है :) :)
रीन हेनरिक

6

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

रख-रखाव

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

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

पठनीयता

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

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

अंत में, आपको "बदबूदार" परीक्षणों से बहुत चिंतित होना चाहिए - वे आपके समय की बर्बादी को समाप्त कर सकते हैं, कोई मूल्य नहीं प्रदान करते हैं।

आपने कहा है:

यूनिट परीक्षण के लिए आमतौर पर विभिन्न "बदबूदार हैक्स" की आवश्यकता होती है जैसे कि स्टबिंग फ़ंक्शन।

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


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

5

आपके लिए दो प्रश्न:

  • क्या आप बिल्कुल सकारात्मक हैं कि आप परीक्षण कर रहे हैं जो आपको लगता है कि आप परीक्षण कर रहे हैं?
  • यदि कोई व्यक्ति इकाई परीक्षण को देखता है, तो क्या वे यह पता लगाने में सक्षम होंगे कि कोड क्या करना चाहिए ?

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

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


5

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


3

अन्य उत्तरों के अलावा यहां।

इकाई परीक्षणों में खराब गुणवत्ता कोड आपकी इकाई परीक्षण सूट तक ही सीमित नहीं है।

यूनिट टेस्टिंग द्वारा भरी गई भूमिकाओं में से एक प्रलेखन है।

यूनिट टेस्ट सूट उन स्थानों में से एक है जो यह पता लगाने के लिए कि एपीआई का उपयोग कैसे किया जाता है।

आपके API के कॉलर को आपके यूनिट टेस्ट सूट के कुछ हिस्सों की नकल करने की संभावना नहीं है, जो आपके खराब टेस्ट-सूट कोड को लाइव कोड को कहीं और संक्रमित करता है।


3

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

प्रोग्रामर "सर्वश्रेष्ठ प्रथाओं" में संलग्न होते हैं जो सौंदर्य कारणों से नहीं होते हैं, या क्योंकि वे "सही" कोड चाहते हैं। यह इसलिए है क्योंकि यह उन्हें समय बचाता है।

  • यह समय बचाता है क्योंकि अच्छा कोड पढ़ना और समझना आसान है।
  • यह समय बचाता है क्योंकि जब आपको एक बग को ठीक करने की आवश्यकता होती है तो इसे ढूंढना आसान और तेज होता है।
  • यह समय बचाता है क्योंकि जब आप कोड को विस्तारित करना चाहते हैं तो ऐसा करना आसान और तेज़ होता है।

तो आपके प्रश्न (मेरे दृष्टिकोण से) क्या मुझे अपना समय बचाना चाहिए या कोड लिखना चाहिए जो मेरा समय बर्बाद करेगा?

उस प्रश्न के लिए मैं केवल यह कह सकता हूं कि आपका समय कितना महत्वपूर्ण है?

FYI करें: स्टबिंग, मॉकिंग और मंकी पैचिंग सभी के वैध उपयोग हैं। वे केवल "गंध" जब उनका उपयोग उचित नहीं है।


2

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


2

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

परीक्षण सेट-अप की जटिलता के आधार पर कोड अधिक जटिल हो सकता है। (httpcontext.current बनाम उदाहरण के लिए एक झूठे एक सटीक निर्माण की कोशिश करने का भयानक राक्षस)

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


0

कोड गंध कोड में केवल एक समस्या है जिसे बाद में किसी बिंदु पर बदलने या समझने की आवश्यकता होती है।

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

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