आवश्यकता या विधि द्वारा विभाजित इकाइयों का परीक्षण


17

मेरे पास एक विधि है जिसके लिए मैं इकाई परीक्षण लिखना चाहता हूं। मैं इसे काफी सामान्य रखने जा रहा हूं क्योंकि मैं इसे लागू करने के तरीके पर चर्चा नहीं करना चाहता। विधि है:

public void HandleItem(item a)
{         
     CreateNewItem();
     UpdateStatusOnPreviousItem();
     SetNextRunDate();
}

इसलिए इस वर्ग के पास एक सार्वजनिक तरीका है जो तब कुछ निजी तरीकों को तर्क करने के लिए कहता है।

इसलिए यूनिट टेस्ट लिखते समय मैं तीनों चीजों की जांच करना चाहता हूं। जैसा कि वे सभी एक ही रन में कहे जाते हैं मैंने सोचा कि मैं इसे एक परीक्षा के रूप में कर सकता हूं:

public void GivenItem_WhenRun_Thenxxxxx
{
     HandleItem(item);
     // Assert item has been created
     // Assert status has been set on the previous item
     // Assert run date has been set
}

लेकिन मुझे लगा कि मैं इसे तीन अलग-अलग परीक्षणों के रूप में भी लिख सकता हूं:

public void GivenItem_WhenRun_ThenItemIsCreated()
{
    HandleItem(item);
}

public void GivenItem_WhenRun_ThenStatusIsUpdatedOnPreviousItem()
{
   HandleItem(item);
}

public void GivenItem_WhenRun_ThenRunDateIsSet()
{
     HandleItem(item);
}

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

क्या इसके साथ लेने के लिए एक अनुशंसित दृष्टिकोण है?

धन्यवाद

जवाबों:


30

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

  • अगर यह तीनों को स्वतंत्र रूप से दूसरे से चलाने के लिए समझ में आता है, क्योंकि जब एक विफल हो जाता है, तो अन्य दो अभी भी विफल नहीं हो सकते हैं, फिर दूसरे दृष्टिकोण का फायदा है कि आपको एक बार में सभी 3 परीक्षणों के लिए पूर्ण परीक्षा परिणाम मिलते हैं। यह तब फायदेमंद हो सकता है जब आपके पास निर्माण करने योग्य समय हो, क्योंकि यह आपको अगला निर्माण करने से पहले एक बार में 3 त्रुटियों को ठीक करने का मौका देता है।

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


2
+1, अच्छी बात है। यह मेरे लिए नहीं था कि निर्माण समय भी एक अड़चन हो सकता है।
किलन फ़ॉथ

1
@KilianFoth: आप C ++ में अक्सर काम नहीं कर रहे हैं :(
Matthieu M.

1
@ मैथ्यूएमएम: निष्पक्ष होने के लिए, सवाल "सी #" टैग किया गया है
डॉक्टर ब्राउन

10

संक्षिप्त उत्तर: यह अधिक महत्वपूर्ण है कि आपके परीक्षण सभी कार्यक्षमता को कवर करते हैं कि वे कैसे करते हैं।

दीर्घ उत्तर: यदि आप अभी भी इन बड़े पैमाने पर समतुल्य समाधानों में से किसी एक को चुनना चाहते हैं, तो आप जो सबसे अच्छा है उसके लिए सहायक मानदंड का उपयोग कर सकते हैं। उदाहरण के लिए,

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

3

एकाधिक मुखर के साथ एक विधि कॉल का उपयोग करें। यहाँ पर क्यों:

जब आप HandleItem (a) का परीक्षण करते हैं, तो आप परीक्षण कर रहे हैं कि विधि ने आइटम को सही स्थिति में लाया है। "प्रति परीक्षण एक जोर" के बजाय, "प्रति परीक्षण एक तार्किक अवधारणा" सोचें।

प्रश्न: अगर कोई CreateNewItem विफल हो जाता है, लेकिन अन्य दो तरीके सफल होते हैं, तो क्या इसका मतलब है कि HandleItem सफलतापूर्वक पूरा हो गया है? मैं अनुमान लगा रहा हूं।

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

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

आप अन्य 3 विधियों को सार्वजनिक करने और स्वतंत्र रूप से उनका परीक्षण करने पर विचार कर सकते हैं। या यहां तक ​​कि उन्हें किसी अन्य वर्ग के लिए निकालने।


0

2 के दृष्टिकोण का उपयोग करें। आपके 1 दृष्टिकोण के साथ, यदि परीक्षण विफल हो जाता है तो आपको पता नहीं चलेगा कि तुरंत क्यों, क्योंकि यह 3 कार्यों में से एक हो सकता है जो विफल हो गया। दूसरे दृष्टिकोण से आप तुरंत जान जाएंगे कि समस्या कहां हुई है। आप अपने टेस्ट सेटअप फ़ंक्शन के अंदर डुप्लिकेट कोड डाल सकते हैं।


-1

IMHO आपको इस विधि के तीन भागों का अलग-अलग परीक्षण करना चाहिए ताकि आप अधिक विशिष्ट रूप से जान सकें जहां चीजें गलत हो रही हैं जब वे दो बार अपने कोड के एक ही हिस्से पर जाने से बचते हैं।


-2

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

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

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