2010-08-20 7 views
9

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

public int FirstInvalidDigitPosition { 
    get { 
     for (int index = 0; index < this.positions.Count; ++index) { 
      if (!this.positions[index].Valid) return index; 
     } 
     throw new InvalidOperationException("Attempt to get invalid digit position whene there are no invalid digits."); 
    } 
} 

मैं भी एक यूनिट परीक्षण लिखना नहीं चाहता जो कोड का प्रयोग नहीं करता जिसे कभी निष्पादित नहीं किया जाना चाहिए।

+1

केवल तथ्य यह है कि आप कहते हैं कि इसे निष्पादित नहीं किया जाना चाहिए और मुझे नहीं पहुंचाया जा सकता है "इसे निकालें"। आपने स्ट्रिंग को यहां प्राप्त करने के लिए अमान्य के रूप में मान्य कर दिया है, इसलिए आप जानते हैं कि संपत्ति कुछ वापस कर देगी। – Michael

उत्तर

22

हैं "फेंक" सवाल में बयान सही मायने में पहुँच योग्य नहीं किसी भी संभावित परिदृश्य के अंतर्गत है तो यह नष्ट कर दिया और के साथ प्रतिस्थापित किया जाना चाहिए: कोड पहुंचा जा सकता है

Debug.Fail("This should be unreachable; please find and fix the bug that caused this to be reached."); 

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

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

पहली समस्या वास्तव में एक समस्या नहीं होनी चाहिए; निश्चित रूप से कोड कवरेज उपकरण को पहुंचने योग्य डीबग-केवल कोड को अनदेखा करने के लिए कॉन्फ़िगर करने योग्य होना चाहिए। लेकिन दोनों समस्या पाश दोबारा लिख ​​कर हल किया जा सकता:

public int FirstInvalidDigitPosition 
{ 
    get 
    { 
     int index = 0; 
     while(true) 
     { 
      Debug.Assert(index < this.positions.Length, "Attempt to get invalid digit position but there are no invalid digits!"); 
      if (!this.positions[index].Valid) return index; 
      index++; 
     } 
    } 
} 

एक वैकल्पिक दृष्टिकोण ताकि आप पहली जगह में समस्या नहीं है कोड पुनर्निर्माण करने के लिए होगा:

public int? FirstInvalidDigitPosition { 
    get { 
     for (int index = 0; index < this.positions.Count; ++index) { 
      if (!this.positions[index].Valid) return index; 
     } 
     return null; 
    } 
} 

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

+0

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

+0

इसके अलावा डीबग.फाइल अभी भी कोड-कवर नहीं होगा, डीबग के साथ उस फेंक को भी बदल देगा। विफल एक संकलन त्रुटि है। –

+0

@ user93422: मैंने आपके उत्तरों को संबोधित करने के लिए अपना जवाब अपडेट कर दिया है। –

4

मुझे समझ में नहीं आता कि आप एक यूनिट परीक्षण क्यों नहीं लिखना चाहते हैं जो "कोड नहीं होना चाहिए" का प्रयोग करता है।

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

यदि आपको लगता है कि यह कोड लिखने लायक है, तो यह इकाई परीक्षण के लायक है। परीक्षण के की

+0

मैं सहमत हूं - कोड लिखना जो "कभी निष्पादित नहीं किया जाना चाहिए" मेरे लिए काफी बर्बाद अभ्यास की तरह लगता है। – EnOpenUK

+0

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

+1

डिज़ाइन को बेहतर बनाने के लिए, मैं एक संपत्ति के बजाय एक विधि का उपयोग करता हूं। एक संपत्ति कॉलर को एक साधारण सदस्य परिवर्तनीय पहुंच की तरह "दिखती है", इसलिए उन्हें * आश्चर्यचकित होने की संभावना है * अगर इसे निष्पादित करने में लंबा समय लगता है, तो दुष्प्रभाव होते हैं (जैसे 'get' कॉल में सदस्य चर बदलना) घटनाओं को निकाल दिया जाएगा, या एक अपवाद फेंकता है। दूसरी तरफ, "नहीं मिला" (उदाहरण के लिए, स्ट्रिंग.इंडेक्सओएफ की तरह) को इंगित करने के लिए एक मान वापस करने के लिए सामान्य है या अपवाद फेंकना - इसलिए एक विधि एक बेहतर डिजाइन विकल्प है। –

3

भाग दोनों चीजें हैं जो होना चाहिए और चीजें हैं जो भी हो सकता है परीक्षण करने के लिए है।

यदि आपके पास कोड पर अमल नहीं किया जाना चाहिए कि है, लेकिन अधिकार के तहत (या गलत) की स्थिति, आपको लगता है कि अपवाद अपने परीक्षण सजाने द्वारा सही परिस्थितियों में होता है (एमएस के यूनिट टेस्ट फ्रेमवर्क में) सत्यापित कर सकते हैं सकता है साथ विधि:

[ExpectedException(typeof(InvalidOperationException))] 
+0

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

+0

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

4

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

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

 
    register = 0 
    test register for zero 
    if non-zero goto dead 
    register = register - 1 
    test register for zero 
    if non-zero goto okay1 
dead: 
    shut everything down 
    goto dead 
okay1: 
    register = register + 1 
    if non-zero goto dead 

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