2010-11-18 12 views
6

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

क्या कोई टीडीडी सर्वोत्तम प्रथाओं और व्यावहारिक आसानी के बीच इस विसंगति को समझा सकता है?

धन्यवाद, एक

उत्तर

14

एक स्थिर विधि का परीक्षण करने के लिए आसान है, लेकिन कुछ है जो सीधे एक स्थिर विधि आम तौर पर कहता है स्थिर विधि उस पर निर्भर के स्वतंत्र परीक्षण करने के लिए आसान नहीं है। गैर-स्थैतिक विधि के साथ आप परीक्षण को आसान बनाने के लिए स्टब/नकली/नकली उदाहरण का उपयोग कर सकते हैं, लेकिन यदि आप जिस कोड का परीक्षण कर रहे हैं, वह स्थैतिक तरीकों को कॉल करता है तो यह प्रभावी तरीके से "हार्ड वायर्ड" प्रभावी ढंग से होता है।

+0

मुझे लगता है कि अवधि आप देख रहे हैं कसकर युग्मित है। –

+1

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

+0

कसकर युग्मित होने के स्थान पर पहली बार "हार्ड वायर्ड" सुनवाई। यह बिल्कुल शानदार है कि शब्दों में बदलाव कैसे समझने में सहायता कर सकता है। – jrahhali

2

स्थिर विधि का परीक्षण करना आसान है। समस्या यह है कि दूसरे कोड का परीक्षण करते समय उस स्थिर विधि से अपना अन्य कोड अलग करने का कोई तरीका नहीं है। कॉलिंग कोड कड़ाई से स्थिर कोड के साथ मिलकर है।

एक स्थिर विधि का संदर्भ कई मॉकिंग ढांचे द्वारा मजाक नहीं किया जा सकता है और न ही इसे ओवरराइड किया जा सकता है।

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

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

3

पूछे जाने वाले प्रश्न का उत्तर मेरी राय में है, "ऑब्जेक्ट ओरिएंटेड ऐसा लगता है कि टीडीडी लोग सोचते हैं।"

क्यों? मुझे नहीं पता। हो सकता है कि वे सभी जावा प्रोग्रामर हैं जो सब कुछ छह इंडिकेशन परतों, निर्भरता इंजेक्शन और इंटरफ़ेस एडाप्टर पर भरोसा करने की बीमारी से संक्रमित हैं।

जावा प्रोग्रामर "बाद में समय बचाने" के लिए सबकुछ आगे बढ़ाना पसंद करते हैं।

मैं आपके टीडीडी में कुछ एग्इल सिद्धांतों को लागू करने की सलाह देता हूं: यदि यह कोई समस्या नहीं पैदा कर रहा है तो इसे ठीक न करें। डिजाइन पर मत करो।

प्रैक्टिस में मुझे लगता है कि अगर स्थैतिक तरीकों का परीक्षण पहले किया जाता है तो वे अपने कॉलर्स में बग का कारण नहीं बनेंगे।

यदि स्थैतिक विधियां जल्दी से निष्पादित होती हैं तो उन्हें नकली की आवश्यकता नहीं होती है।

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

यदि आपको एक स्थिर विधि का नकल करने की आवश्यकता है तो याद रखें कि ओओ प्रोग्रामिंग के के बाहर करने के तरीके हैं।

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

+0

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

0

यह सलाह अधिकांश भाग के लिए सच है .. लेकिन हमेशा नहीं। मेरी टिप्पणी सी ++ विशिष्ट नहीं कर रहे .. स्थिर तरीके (जो शुद्ध/राज्यविहीन कार्य हैं) के लिए

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

चलें एक उदाहरण लेते

public class MyStaticClass 
{ 
    static int __count = 0; 
    public static int GetAddCount() 
    { return ++__count; } 

    public static int Add(int operand1, int operand2) 
    { return operand1 + operand2; } 

    // needed for testability 
    internal static void ResetCount() 
    { 
    __count = 0; 
    } 
} 

... 

//test1 
MyStaticClass.Add(2,3);  // => 5 
MyStaticClass.GetAddCount(); // => 1 

// test2 
MyStaticClass.Add(2,3); // => 5 
//MyStaticClass.ResetCount(); // needed for tests 
MyStaticClass.GetAddCount(); // => unless Reset is done, it can differ from 1 
संबंधित मुद्दे