क्या सरल (स्व-निहित) कार्यों के लिए परीक्षण रखने की आवश्यकता है?


36

इस पर विचार करो:

public function polynominal($a, $b, $c, $d)
{
    return  $a * pow($x, 3) + $b * pow($x, 2) + $c * $x + $d;
}

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

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


32
क्या यह हर फ़ंक्शन के लिए सही नहीं है कि जब तक आप अपना कोड नहीं बदलते हैं, अगर यह कल काम करता है, तो यह कल भी काम करेगा? मुद्दा यह है कि सॉफ्टवेयर को बदल दिया गया है।
5gon12eder

3
क्योंकि कोई भी override_function('pow', '$a,$b', 'return $a * $b;');उनके सही दिमाग में कभी नहीं लिखेगा ... या जटिल संख्याओं को संभालने के लिए इसे फिर से लिखने की कोशिश करेगा।

8
तो ... उम ... कि "बग मुक्त कोड साबित" ... यह एक बग है

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

6
इसके अलावा, फ़ंक्शन हॉर्नर के रूप में बदलाव के लिए एक महान उम्मीदवार है (($a*$x + $b)*$x + $c)*$x + $dजो गलत होना आसान है, लेकिन अक्सर काफी तेज होता है। सिर्फ इसलिए कि आपको लगता है कि यह अभ्यस्त परिवर्तन अभिप्रेत नहीं है।
माइकल एंडरसन

जवाबों:


78

प्रतिगमन परीक्षण

यह सब प्रतिगमन परीक्षण के बारे में है ।

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

विचलित होने के कारण, वह दो स्थिरांक का आविष्कार करता है।

वह कोड करता है, और सब कुछ ठीक काम करने लगता है, क्योंकि प्रत्येक प्रतिबद्ध के बाद कोई प्रतिगमन परीक्षण नहीं चल रहा है।

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

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

एक पक्ष प्रभाव ...

दरअसल, ज्यादातर रिफ़ेक्टरिंग रिग्रेशन टेस्टिंग पर आधारित होती है। एक छोटा सा बदलाव करें। परीक्षा। यदि यह गुजरता है, तो सब कुछ ठीक है।

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

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

आवश्यकताओं में परिवर्तन

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

यह सब झंझट क्यों? बाद में उन्हें जोड़ने के लिए परीक्षणों को क्यों हटाया गया? आप उन्हें पहले स्थान पर रख सकते थे।


पेडीक नोट: कुछ भी जोखिम मुक्त नहीं है। ;)
jpmc26

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

एक और पेडीक नोट: कुछ "जादू" संख्या वास्तव में ठीक हैं, और उन्हें स्थिरांक के साथ बदलना एक बुरा विचार है।
Deduplicator

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

@jwenting: सिर्फ उस नोट को जोड़ा क्योंकि मेनमा ने लिखा है "इस बदलाव को करने में कुछ भी गलत नहीं है"।
डिडुप्लीकेटर

45

क्योंकि कुछ भी इतना सरल नहीं है कि कीड़े न हों।

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

सिवाय इसके एक बग ...

public function polynominal($a, $b, $c, $d)
{
    return  $a * pow($x, 3) + $b * pow($x, 2) + $c * $x + $d;
}

$xआपके कोड के लिए एक इनपुट के रूप में परिभाषित नहीं किया गया है, और भाषा या रनटाइम, या स्कूपिंग के आधार पर, आपका फ़ंक्शन काम नहीं कर सकता है, अमान्य परिणाम हो सकता है, या किसी स्पेसशिप को क्रैश कर सकता है


परिशिष्ट:

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

अतिरिक्त नोट में कोड कवरेज सेवाएँ (जैसे coveralls.io) हैं जो कवरेज का एक अच्छा संकेत देती हैं जो एक परीक्षण सूट प्रदान करता है। कोड की प्रत्येक पंक्ति को कवर करने से आप परीक्षण करने वाले मात्रा का एक सभ्य मीट्रिक (यदि गुणवत्ता नहीं है) देते हैं। बहुत सारे छोटे परीक्षणों के संयोजन में, ये सेवाएं कम से कम आपको बताती हैं कि ऐसा होने पर बग की तलाश नहीं करनी चाहिए।

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


एक वैकल्पिक समाधान है: गैर-गतिशील गैर-कमजोर भाषाओं पर स्विच करना। यूनिट परीक्षण आमतौर पर अपर्याप्त रूप से मजबूत संकलन-समय सत्यापन के लिए एक समाधान है और कुछ भाषाएँ इस तरह की अच्छी हैं। enikwipedia.org/wiki/Agda_(programming_language)
Den

21

हाँ। यदि हम 100% आत्मविश्वास के साथ, निश्चितता के साथ कह सकते हैं: यह फ़ंक्शन कभी भी संपादित नहीं किया जाएगा और कभी भी ऐसे संदर्भ में नहीं चलेगा, जो इसे विफल कर सकता है - यदि हम यह कह सकते हैं कि, हम परीक्षणों को छोड़ सकते हैं और प्रत्येक पर कुछ मिलीसेकंड बचा सकते हैं CI का निर्माण।

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

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


मुझे लगता है कि यह एक बहुत अच्छा बिंदु है जिसे आप यहाँ ला रहे हैं। मैं पहले से ही दो लोगों को कुछ छोटी कार्यक्षमता के लिए परीक्षण रखने के बारे में बहस करते हुए घंटों बिताते देख सकता हूं ।
कपोल १

@ कपोल: एक तर्क नहीं, यह निर्धारित करने के लिए एक बैठक कि कौन जा सकता है और कौन ठहर सकता है, और तय करने के लिए किन मानदंडों का उपयोग किया जाना चाहिए, साथ ही साथ मापदंड का दस्तावेज कहां है, और अंतिम निर्णय पर कौन हस्ताक्षर
करेगा

12

अन्य उत्तरों में कहा गया सब कुछ सही है, लेकिन मैं एक और जोड़ दूंगा।

प्रलेखन

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

यह एक बग को आसान और कम भ्रम में डाल सकता है।

हर कोई बहुपद, ज्यामिति, या यहां तक ​​कि बीजगणित को याद नहीं करता है :) लेकिन संस्करण नियंत्रण में जाँच की गई एक अच्छी इकाई परीक्षण मुझे याद होगा।

प्रलेखन के रूप में यह कितना उपयोगी हो सकता है, उदाहरण के लिए, जैस्मीन परिचय देखें: http://jasmine.github.io/edge/introduction.html इसे लोड करने के लिए कुछ सेकंड दें, फिर नीचे स्क्रॉल करें। आप पूरे जैस्मीन एपीआई को यूनिट टेस्ट आउटपुट के रूप में देखेंगे।

[@Warbo से फीडबैक के आधार पर अपडेट] टेस्ट के लिए अप-टू-डेट होने की गारंटी दी जाती है क्योंकि अगर वे नहीं हैं, तो वे असफल हो जाएंगे, जो आमतौर पर सीआई का उपयोग करने पर बिल्ड विफलता का कारण होगा। बाहरी प्रलेखन कोड के स्वतंत्र रूप से बदल जाता है, और इसलिए जरूरी नहीं है कि तारीख तक।


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

मैं यह जोड़ना चाहता हूं कि कुछ भाषाएं, जैसे D और Rust, अपनी प्रलेखन पीढ़ी को अपनी इकाई परीक्षण के साथ एकीकृत करती हैं, इसलिए आप एक ही कोड के दोनों टुकड़े एक इकाई परीक्षण में संकलित कर सकते हैं और HTML प्रलेखन में सम्मिलित हो सकते हैं
Idan Arye

2

वास्तविकता की जांच

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

आपके पास बजट है। आपका काम उस बजट पर सबसे अच्छा उत्पाद प्राप्त करना है, जो कि "सर्वश्रेष्ठ" की परिभाषा के लिए आप एक साथ परिमार्जन कर सकते हैं (यह परिभाषित करने के लिए एक आसान शब्द नहीं है)। कहानी का अंत।

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

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

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


4
इस मामले में, पहले से ही एक परीक्षण था, इसलिए यह सवाल नहीं है कि क्या उन्हें लिखना है, लेकिन क्या उन्हें प्रतिबद्ध करना है और उन्हें प्रत्येक निर्माण या रिलीज़ के साथ चलाना है या सभी परीक्षण चलाने के लिए जो भी शेड्यूल है।
पाओलो एबरमन

0

हां, टेस्ट कराते रहें, उन्हें चलाते रहें और पास करते रहें।

यूनिट टेस्ट आपको (और दूसरों को) खुद (और खुद) से बचाने के लिए होते हैं।

परीक्षणों को एक अच्छा विचार क्यों रखा जा रहा है;

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

2
यह प्रदान किए गए अन्य उत्तरों पर पर्याप्त रूप से कुछ भी पेश नहीं करता है।

1
पहले इसे पोस्ट करने में कोई समस्या थी, लेकिन पूर्वव्यापी में, यह एक अच्छा सारांश है। मैं इसे हटा दूंगा।
नील

-1

डेवलपर दस्तावेज़

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

उपयोगकर्ता दस्तावेज़

  • खराब डॉक्स को लंबित करते हुए, मैं देख सकता हूं और देख सकता हूं कि {शून्य, नकारात्मक मान, खाली सेट, आदि} स्वीकार किए जाते हैं और अपेक्षित वापसी मूल्य क्या है।
  • यह एक अच्छा उदाहरण भी देता है कि मुझे ऑब्जेक्ट / फ़ंक्शन का उपयोग कैसे करना चाहिए

1
ऐसा लगता नहीं है कि पहले से बनाए गए बिंदुओं पर कुछ भी पर्याप्त नहीं है। यहां तक ​​कि "अच्छा सारांश" पहले से ही पोस्ट किया गया है (मेरे स्वाद के लिए यह इतना अच्छा नहीं है लेकिन ओह अच्छी तरह से है)
gnat
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.