2010-03-20 17 views
15

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

मैं मुख्य रूप से उन परिस्थितियों के लिए सवाल पूछ रहा हूं जहां आप जिस विधि का परीक्षण कर रहे हैं वह उचित रूप से सरल है और इसके उचित ऑपरेशन को एक मिनट के लिए कोड पर देखकर सत्यापित किया जा सकता है।

(माणिक में)

सरलीकृत उदाहरण:

def concat_strings(str1, str2) 
    return str1 + " AND " + str2 
end 

सरलीकृत कार्यक्षमता को दोहराने वाला उपरोक्त विधि के लिए परीक्षण:

def test_concat_strings 
    10.times do 
    str1 = random_string_generator 
    str2 = random_string_generator 
    assert_equal (str1 + " AND " + str2), concat_strings(str1, str2) 
    end 
end 

मैं समझता हूँ कि अधिकांश समय विधि आप कर रहे हैं परीक्षण सरल नहीं होगा इस तरह से ऐसा करने के लिए पर्याप्त है। लेकिन मेरा सवाल बनी हुई है; क्या यह कुछ परिस्थितियों में एक वैध पद्धति है (क्यों या क्यों नहीं)?

+0

मैं नहीं भी परिचित बुद्धि पहले परिदृश्य - जहां एक इकाई परीक्षण के लिए एक विधि की कार्यक्षमता डुप्लिकेट, आप थोड़ा विस्तार से बता सकते हैं? – RobS

+0

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

+0

बहुत अच्छा सवाल - मुझे लगता है कि यह एक बार और केवल एक बार के नियम के लिए अपवाद है .. जब तक मुझे नहीं पता कि यह सही तरीके से कैसे प्रतिक्रिया करें। – Gishu

उत्तर

2

यह एक विवादास्पद रुख है, लेकिन मेरा मानना ​​है कि unit testing using Derived Values है कि मनमाने ढंग से हार्ड-कोडित इनपुट और आउटपुट का उपयोग करने के लिए कहीं बेहतर है।

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

परिणाम के खिलाफ परीक्षण करने के लिए Derived Values का उपयोग करके स्पष्ट इनपुट परीक्षण इनपुट और अपेक्षित आउटपुट के बीच स्थापित करता है।

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

एक अतिरिक्त लाभ यह है कि आप use fewer unit tests to cover the desired functionality कर सकते हैं, और यहां तक ​​कि उन्हें एक ही समय में अधिक संवादात्मक बना सकते हैं। अंतिम परिणाम terser और अधिक रखरखाव इकाई परीक्षण है।

2

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

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

1

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

परीक्षण करता है, तो कार्यक्षमता समय के साथ नहीं बदला है (अस्थायी) पुनर्रचना के दौरान उपयोगी हो सकता है। लेकिन आप इस तरह के छोटे तरीकों को कितनी बार रिफैक्टर करते हैं?

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

अपने परीक्षण वास्तव में एक fuzz test तरह दिखता है। फ़ज़ परीक्षण बहुत उपयोगी हो सकते हैं, लेकिन यूनिट परीक्षण में पुनरुत्पादन के कारण यादृच्छिकता से बचा जाना चाहिए।

8

ही कार्यान्वयन का उपयोग करके कार्यक्षमता का परीक्षण, कुछ भी परीक्षण नहीं होता है। अगर इसमें कोई बग है, तो दूसरा भी होगा।

लेकिन परीक्षण के लिए एक वैकल्पिक कार्यान्वयन के साथ तुलना करके एक मान्य तरीका है। उदाहरण के लिए, आप एक छोटे से पुनरावर्ती, फिर भी उसी विधि के धीमे कार्यान्वयन के साथ तुलना करके फाइबोनैकी संख्याओं की गणना करने की एक पुनरावृत्ति (तेज़) विधि का परीक्षण कर सकते हैं।

इसका एक बदलाव कार्यान्वयन का उपयोग कर रहा है, जो केवल विशेष मामलों के लिए काम करता है। बेशक उस मामले में आप केवल ऐसे विशेष मामलों के लिए इसका उपयोग कर सकते हैं।

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

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

1

एक यूनिट-टेस्ट अपने कोड का उपयोग करें, जो आप उपयोग कर रहे भाषा के हिस्से के रूप में कुछ नहीं करते हैं।

यदि कोड का तर्क किसी विशेष तरीके से स्ट्रिंग को जोड़ना है, तो आपको इसके लिए परीक्षण करना चाहिए - अन्यथा आपको अपनी भाषा/ढांचे पर भरोसा करना होगा।

अंत में, आपको पहले "अर्थ के साथ" विफल होने के लिए अपने यूनिट परीक्षण बनाना चाहिए। दूसरे शब्दों में, यादृच्छिक मान नहीं किया जाना चाहिए (जब तक आप परीक्षण कर रहे हैं अपने यादृच्छिक संख्या जनरेटर यादृच्छिक मान के एक ही सेट नहीं लौटा रहा है!)

0

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

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

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

0

हां। यह मुझे भी परेशान करता है .. हालांकि मैं कहूंगा कि यह गैर-तुच्छ गणनाओं के साथ अधिक प्रचलित है। आदेश जब कोड में परिवर्तन, कुछ प्रोग्रामर एक ISX = एक्स परीक्षण है, जो हमेशा SUT

  • पर ध्यान दिए बिना सफल होता कार्यक्षमता डुप्लिकेट करने के बारे में लिखने के

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

def doubler(x); x * 2; end 

def test_doubler() 
    input, expected = 10, doubler(10) 

    assert_equal expected, doubler(10) 
end 

दूर refactor नहीं होना चाहिए अगर मैं doubler बदल (एक्स) होने के लिए एक Tripler, ऊपर परीक्षण असफल नहीं होंगे। def doubler(x); x * 3; end

हालांकि इस होगा एक: इकाई परीक्षण में

def test_doubler() 
    assert_equal(20, doubler(10)) 
end 
  • अनियमितता - मत करो।
यादृच्छिक डेटासेट के बजाय

, परीक्षण के लिए स्थिर प्रतिनिधि डेटा बिंदुओं का चयन और एक XUnit RowTest/testcase का उपयोग diff डेटा जानकारी के साथ परीक्षण चलाने के लिए। n इनपुट सेट इकाई के लिए समान हैं, तो चुनें 1. ओपी में परीक्षण एक खोजपूर्ण परीक्षण के रूप में इस्तेमाल किया जा सकता/या अतिरिक्त प्रतिनिधि इनपुट सेट निर्धारित करने के लिए। यूनिट परीक्षणों को दोहराने की आवश्यकता है (q # 61400 देखें) - यादृच्छिक मूल्यों का उपयोग इस उद्देश्य को हरा देता है।

+0

मैं कि क्या ठीक उसी विधि का फिर से उपयोग करने के लिए के बारे में पूछ नहीं किया गया था, लेकिन केवल कुछ या SUT की कार्यक्षमता के सभी एक से समझा जा सकता ढंग से परीक्षा के लिए उम्मीद मूल्य उत्पन्न करने के लिए फिर से लागू करने। –

+0

@ डैनियल - जैसा कि मैंने दूसरे पैरा में उल्लेख किया है, परीक्षणों में पठनीयता के लिए आपको तर्क को डुप्लिकेट करना होगा। जैसे 'EXPECTED_TOTAL_PRICE = lineitems.inject {| sum, item | योग + = (item.price * item.quantity)} * (1-DISCOUNT_RATE) ' – Gishu

+0

सहमत है। मुझे लगता है कि मैंने क्या करना है इसके बजाय, मैंने क्या करना है इसके सुझाव के रूप में आपके पहले उदाहरण का गलत अर्थ दिया :-) –

संबंधित मुद्दे