2010-07-15 22 views
156

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

यह एक बड़ा काम है, ज्यादातर परीक्षण करने के लिए कक्षाओं की संख्या के कारण यह भी है क्योंकि लेखन परीक्षण मेरे लिए बिल्कुल नया है।

मैंने पहले से ही कक्षाओं के समूह के लिए परीक्षण लिखे हैं, लेकिन अब मैं सोच रहा हूं कि मैं इसे सही कर रहा हूं या नहीं।

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

यह सिर्फ एक भावना है, और जैसा कि पहले कहा गया था, मुझे परीक्षण का कोई अनुभव नहीं है। अगर वहां कुछ और अनुभवी परीक्षकों ने मुझे सलाह दी है कि मौजूदा ऐप के लिए महान परीक्षण कैसे लिखें, तो इसकी सराहना की जाएगी।

संपादित करें: मुझे स्टैक ओवरफ़्लो का शुक्रिया अदा करना अच्छा लगेगा, मेरे पास बहुत कम इनपुट था जो 15 मिनट में मैंने ऑनलाइन पढ़ने के अधिक घंटों का उत्तर दिया था।

उत्तर

112

मेरे परीक्षण सिर्फ इतना कसकर विधि (, सभी codepath परीक्षण कुछ भीतरी तरीकों की उम्मीद कुछ तर्क के साथ, कई बार कहा जा करने के लिए) के लिए बाध्य कर लगता है, ऐसा लगता है कि है कि अगर मैं कभी विधि refactor, परीक्षण का असफल होने पर भी परीक्षण विफल हो जाएंगे।

मुझे लगता है कि आप इसे गलत कर रहे हैं।

एक इकाई परीक्षण करना चाहिए:

  • परीक्षण एक विधि
  • कि के रूप में परिणाम की उम्मीद है

यह अंदर नहीं देखना चाहिए

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

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

    आपको अपेक्षित परिणाम गतिशील रूप से उत्पन्न करने के लिए विधि (या इसका उपयोग करने वाला आंतरिक कोड) का उपयोग नहीं करना चाहिए। अपेक्षित परिणाम आपके परीक्षण मामले में कड़ी-कोडित होना चाहिए ताकि कार्यान्वयन में परिवर्तन होने पर यह परिवर्तित न हो। - केवल कि परिणाम सही है

    testAdd() 
    { 
        int x = 5; 
        int y = -2; 
        int expectedResult = 3; 
    
        Calculator calculator = new Calculator(); 
        int actualResult = calculator.Add(x, y); 
        Assert.AreEqual(expectedResult, actualResult); 
    } 
    

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

  • +7

    बहुत बहुत धन्यवाद, आपका उत्तर अधिक पूरा था। अब मैं बेहतर समझता हूं कि नकली वस्तुएं वास्तव में किसके लिए हैं: मुझे अन्य तरीकों, केवल प्रासंगिक लोगों को हर कॉल करने की आवश्यकता नहीं है। मुझे यह जानने की भी आवश्यकता नहीं है कि चीजें कैसे की जाती हैं, लेकिन वे सही तरीके से करते हैं। – pixelastic

    +1

    मैं सम्मान से सोचता हूं कि _you_ यह गलत कर रहा है। यूनिट परीक्षण कोड निष्पादन प्रवाह (सफेद बॉक्स परीक्षण) के बारे में हैं। ब्लैक बॉक्स परीक्षण (आप जो सुझाव दे रहे हैं) आम तौर पर कार्यात्मक परीक्षण (सिस्टम और एकीकरण परीक्षण) में उपयोग की जाने वाली तकनीक है। – Wes

    14

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

    Moving existing code to Test Driven Development

    मैं दूसरे स्वीकार किए जाते हैं जवाब की पुस्तक सिफारिश, लेकिन उस से परे और भी है वहां उत्तर में जुड़ी जानकारी।

    +3

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

    +1

    संभवतः स्वीकृत उत्तर बदल गया है। लिंकक्स का एक जवाब है जो रॉय ओशरोव द्वारा यूनिट परीक्षण की कला की सिफारिश करता है, http://www.manning.com/osherove/ – thelem

    5

    परीक्षण करने जा रहे तरीके को लिखने से पहले यूनिट टेस्ट लिखने का प्रयास करें।

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

    आपको हमेशा विधि के परिणामों का परीक्षण करना चाहिए, न कि विधि को उन परिणामों को कैसे प्राप्त किया जाता है।

    +0

    हां, मुझे ऐसा करने में सक्षम होना अच्छा लगेगा, सिवाय इसके कि विधियां पहले ही लिखी गई हैं। मैं बस उनका परीक्षण करना चाहता हूं। मैं भविष्य में विधियों से पहले परीक्षण लिखूंगा, वैसे। – pixelastic

    +1

    @ पिक्सेलैस्टिक ने दिखाया कि विधियों को लिखा गया है? – committedandroider

    10

    अपने कोड का पूर्ण कवरेज प्राप्त करने के लिए परीक्षण न लिखें। परीक्षणों को लिखें जो आपकी आवश्यकताओं की गारंटी देते हैं। आप कोडपैथ खोज सकते हैं जो अनावश्यक हैं। इसके विपरीत, यदि वे आवश्यक हैं, तो वे किसी प्रकार की आवश्यकता को पूरा करने के लिए हैं; यह पता लगाएं कि यह क्या है और आवश्यकता का परीक्षण करें (पथ नहीं)।

    अपने परीक्षणों को छोटा रखें: एक परीक्षण प्रति आवश्यकता।

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

    +0

    धन्यवाद, यह समझ में आता है कि केवल एक ही समय में छोटी आवश्यकता के लिए छोटे परीक्षण होते हैं। सबक सीखा। – pixelastic

    10

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

    +0

    धन्यवाद! मुझे एहसास हुआ कि मैं इसे गलत कर रहा था, लेकिन वास्तव में मुझे कोई बता रहा है कि बेहतर है। – pixelastic

    3

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

    When I'm writing tests for a method, I have the feeling of rewriting a second time what I   
    already wrote in the method itself. 
    My tests just seems so tightly bound to the method (testing all codepath, expecting some  
    inner methods to be called a number of times, with certain arguments), that it seems that 
    if I ever refactor the method, the tests will fail even if the final behavior of the 
    method did not change. 
    

    ऐसा इसलिए है क्योंकि आप अपना कोड लिखने के बाद अपने परीक्षण लिख रहे हैं। यदि आपने इसे दूसरी तरफ किया (पहले परीक्षणों को लिखा) तो यह इस तरह से महसूस नहीं करेगा। http://www.manning.com/osherove/

    यह सब सर्वोत्तम प्रथाओं, कर के, और न इकाई परीक्षण के लिए की बताते हैं:

    +0

    ब्लैक बॉक्स उदाहरण के लिए धन्यवाद, मैंने इसे इस तरह से नहीं सोचा है। मेरी इच्छा है कि मैंने पहले इकाई परीक्षण की खोज की, लेकिन दुर्भाग्य से, यह मामला नहीं है और मैं परीक्षण जोड़ने के लिए _legacy_ ऐप से फंस गया हूं।क्या मौजूदा परियोजना में परीक्षणों को तोड़ने के बिना परीक्षण जोड़ने का कोई तरीका नहीं है? – pixelastic

    +1

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

    +0

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

    3

    इस इकाई के परीक्षण के लिए सबसे अच्छा किताब है।

    +0

    धन्यवाद, मैं इसे देख लूंगा। मैंने टीडीडी के बारे में केंट बेक बुक खरीदा लेकिन मुझे लगता है कि मुझे सबसे पहले अपने मौजूदा ऐप को कवर करने की आवश्यकता है। – pixelastic

    22

    यूनिट परीक्षण के लिए, मुझे टेस्ट ड्राइव (परीक्षण पहले, कोड दूसरा) और कोड पहले पाया गया, दूसरा परीक्षण बेहद उपयोगी है।

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

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

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

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

    +1

    अच्छा जवाब, मुझे विश्वास दिलाया कि कोड के बाद परीक्षण लिखना अभी भी उपयोगी और संभव हो सकता है। – pixelastic

    +1

    एक आदर्श हालिया उदाहरण। मेरे पास एक बहुत ही सरल काम था। इसे सच कहें, यह एक बात करता है, झूठा यह दूसरा करता है। बहुत आसान। यह सुनिश्चित करने के लिए कि यह कार्य करने का इरादा रखता है, 4 परीक्षणों की जांच करना था। मैं थोड़ा सा व्यवहार बदलता हूं। परीक्षण चलाएं, एक समस्या पाओ। मजाकिया बात यह है कि एप्लिकेशन का उपयोग करते समय समस्या प्रकट नहीं होती है, यह केवल एक जटिल मामले में है जो यह करता है। परीक्षण मामले में यह पाया गया और मैंने खुद को सिरदर्द के घंटे बचा लिया। –

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