यूनिट परीक्षण के लिए नया, महान परीक्षण कैसे लिखें? [बन्द है]


267

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

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

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

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

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

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


1
यह इकाई परीक्षण के लिए सबसे अच्छी पुस्तक है: manning.com/osherove यह सभी सर्वोत्तम प्रथाओं, डू, और न ही यूनिट परीक्षण के लिए समझाता है।
एरवी बी जूल

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

जवाबों:


187

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

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

एक यूनिट टेस्ट होना चाहिए:

  • एक विधि का परीक्षण करें
  • उस विधि के लिए कुछ विशिष्ट तर्क प्रदान करते हैं
  • परीक्षण करें कि परिणाम अपेक्षित है

यह देखने के लिए विधि के अंदर नहीं देखना चाहिए कि यह क्या कर रहा है, इसलिए आंतरिक को बदलने से परीक्षण विफल नहीं होना चाहिए। आपको सीधे परीक्षण नहीं करना चाहिए कि निजी तरीकों को बुलाया जा रहा है। यदि आप यह जानने में रुचि रखते हैं कि क्या आपके निजी कोड का परीक्षण किया जा रहा है, तो एक कोड कवरेज टूल का उपयोग करें। लेकिन इस पर ध्यान न दें: 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);
}

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


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

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

1
"एक इकाई परीक्षण को एक विधि का परीक्षण करना चाहिए" मैं वास्तव में असहमत हूं। एक इकाई परीक्षण को एक तार्किक अवधारणा का परीक्षण करना चाहिए। जबकि अक्सर इसे एक विधि के रूप में दर्शाया जाता है, ऐसा हमेशा नहीं होता है
robertmain

35

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

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

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

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

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


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

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

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

18

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

मौजूदा कोड को टेस्ट ड्रिवेन डेवलपमेंट में ले जाना

मैं स्वीकार किए गए उत्तर की पुस्तक की अनुशंसा को दूसरा मानता हूं, लेकिन इससे आगे के उत्तरों में अधिक जानकारी जुड़ी हुई है।


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

2
संभवतः स्वीकृत उत्तर बदल गया है। वहाँ Linx से एक जवाब है कि रॉय Osherove, द्वारा इकाई परीक्षण की कला की सिफारिश की गई है manning.com/osherove
थेलेम

15

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

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

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


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

13

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


धन्यवाद ! मुझे लग रहा था कि मैं इसे गलत कर रहा हूं, लेकिन किसी को वास्तव में मुझे बताना बेहतर है।
19-03 को पिक्सेल

8

परीक्षण करने की विधि लिखने से पहले एक यूनिट टेस्ट लिखने का प्रयास करें।

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

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


हां, मैं ऐसा करने में सक्षम होना चाहूंगा, सिवाय इसके कि विधियां पहले से लिखी गई हैं। मैं सिर्फ उनका परीक्षण करना चाहता हूं। मैं भविष्य में तरीकों से पहले परीक्षण लिखूंगा, थ।
पिक्सेल

2
@pixelastic यह ढोंग करता है कि विधियाँ लिखी गई हैं?
committedandroider

4

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

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.

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


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

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

भी, अपनी उम्मीदों के साथ वास्तव में विशिष्ट हो। न केवल यह दावा करें कि परीक्षण एक वस्तु लौटाता है, परीक्षण करें कि उस वस्तु के विभिन्न मूल्य हैं। परीक्षण करें कि जब कोई मान शून्य माना जाता है, कि यह है। आप कुछ परीक्षणों को जोड़ने के बाद कुछ रीफैक्टरिंग करके, जो आप करने के लिए थे, उसे थोड़ा सा तोड़ सकते हैं।
hvgotcodes
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.