क्या मुझे निजी तरीकों या केवल सार्वजनिक लोगों का परीक्षण करना चाहिए? [बन्द है]


348

मैंने इस पोस्ट को निजी तरीकों का परीक्षण करने के तरीके के बारे में पढ़ा है । मैं आमतौर पर उनका परीक्षण नहीं करता हूं, क्योंकि मैंने हमेशा सोचा था कि केवल सार्वजनिक तरीकों का परीक्षण करना तेजी से होगा जो ऑब्जेक्ट के बाहर से बुलाया जाएगा। क्या आप निजी तरीकों का परीक्षण करते हैं? क्या मुझे हमेशा उनका परीक्षण करना चाहिए?



"क्या मुझे निजी सहायकों का परीक्षण करना चाहिए?" हाँ। "क्या मुझे सीधे निजी सहायकों का परीक्षण करना चाहिए?" यह निर्भर करता है, आम तौर पर यदि आप उन्हें सार्वजनिक इंटरफ़ेस के माध्यम से आसानी से परीक्षण कर सकते हैं, तो उन्हें सीधे परीक्षण क्यों करें? यदि यह सार्वजनिक इंटरफ़ेस के माध्यम से सहायकों के सभी पहलुओं का परीक्षण करने के लिए जटिल हो जाता है, तो क्या घटक ने एक इकाई के रूप में अपने अस्तित्व को रेखांकित किया है?
मिहाई दानिला

जवाबों:


328

मैं निजी तरीकों का परीक्षण नहीं करता हूं। एक निजी पद्धति एक कार्यान्वयन विवरण है जिसे कक्षा के उपयोगकर्ताओं के लिए छिपाया जाना चाहिए। निजी तरीकों का परीक्षण करना अतिक्रमण को तोड़ता है।

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


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

254
यह कहना कि निजी तरीकों के परीक्षण की आवश्यकता नहीं है, यह कहने की तरह है कि जब तक कार ठीक है, तब तक ठीक है, और इससे कोई फर्क नहीं पड़ता कि हुड के नीचे क्या है। लेकिन यह जानना अच्छा नहीं होगा कि अंदर कुछ केबल ढीली होने लगी है - भले ही उपयोगकर्ता कुछ भी देख नहीं रहा हो? ज़रूर, आप सब कुछ सार्वजनिक कर सकते हैं, लेकिन क्या बात है? आप हमेशा कुछ निजी तरीके चाहते हैं।
फ्रैंक

37
"एक निजी पद्धति एक कार्यान्वयन विवरण है जिसे कक्षा के उपयोगकर्ताओं के लिए छिपाया जाना चाहिए।" लेकिन क्या वास्तव में "नियमित" (रनटाइम) उपयोगकर्ताओं के रूप में वर्ग के इंटरफ़ेस के एक ही तरफ परीक्षण हैं? ;)
mlvjrr

34
किसी भी चीज़ को आप किसी अन्य वर्ग में परीक्षण करने के लिए बाहर निकालने का खतरा यह है कि आप अपने उत्पाद के ओवर-इंजीनियरिंग के खत्म होने और एक लाख पुन: प्रयोज्य घटकों के साथ समाप्त हो सकते हैं जो कभी भी पुनः उपयोग में नहीं आते हैं।
occulus

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

293

परीक्षण का उद्देश्य क्या है?

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

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

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

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


72
यहाँ समस्या यह है कि "भविष्य के कोड में परिवर्तन" का तात्पर्य किसी वर्ग के आंतरिक कामकाज को फिर से दिखाना है। ऐसा अक्सर होता है कि परीक्षण लिखने से रिफैक्टिंग में बाधा उत्पन्न होती है।
आउटलॉव प्रोग्रामर

40
इसके अलावा, यदि आप लगातार अपने यूनिट परीक्षणों को बदल रहे हैं, तो आप अपने परीक्षण में सभी निरंतरता खो चुके हैं और आप संभावित रूप से इकाई परीक्षणों में खुद ही कीड़े पैदा कर रहे हैं।
17 का 26

6
@ 17 यदि परीक्षण और कार्यान्वयन समान रूप से संशोधित किए गए हैं (जैसा कि, ऐसा लगता है। यह इस तरह का होना चाहिए), बहुत कम समस्याएं होंगी।
एमएलवल्जर

11
@ सौरोनॉर्ड, आप निजी विधियों का परीक्षण करने का कारण यह है क्योंकि यदि आप केवल सार्वजनिक विधियों का परीक्षण करते हैं, तो परीक्षण विफल होने पर हम सीधे यह नहीं जानते कि विफलता का मूल कारण कहां है। यह testDoSomething()या तो में हो सकता है testDoSomethingPrivate()। यह परीक्षण को कम मूल्यवान बनाता है। । निजी परीक्षण के कुछ और कारण है stackoverflow.com/questions/34571/... :
Pacerier

3
@Pacerier आपके कोड का परीक्षण करने और एक सतत स्वचालित परीक्षण प्रक्रिया होने में भी अंतर है। आपको अपनी निजी विधि को स्पष्ट रूप से सुनिश्चित करना चाहिए, लेकिन आपके पास निजी विधि से युग्मन परीक्षण नहीं होना चाहिए, क्योंकि यह सॉफ्टवेयर के उपयोग के मामले का हिस्सा नहीं है।
डिडियर ए।

150

मैं डेव थॉमस और एंडी हंट की सलाह का पालन करते हुए अपनी पुस्तक प्रागैमैटिक यूनिट टेस्टिंग :

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

लेकिन कभी-कभी मैं खुद को निजी तरीकों का परीक्षण करने से नहीं रोक सकता क्योंकि यह मुझे विश्वास दिलाता है कि मैं पूरी तरह से मजबूत कार्यक्रम बना रहा हूं ।


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

61

मैं निजी कार्यों का परीक्षण करने के लिए मजबूर महसूस कर रहा हूं क्योंकि मैं हमारी परियोजना में नवीनतम क्यूए सिफारिश का अधिक से अधिक पालन कर रहा हूं:

प्रति फ़ंक्शन साइक्लोमैटिक जटिलता में 10 से अधिक नहीं ।

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

यह वास्तव में अच्छा है, क्योंकि कॉलस्टैक को पढ़ना बहुत आसान है (एक बड़े फ़ंक्शन के भीतर बग के बजाय, मेरे पास सब-उप-फ़ंक्शन में एक बग है, कॉलस्टैक में पिछले कार्यों के नाम से मुझे समझने में मदद करने के लिए। 'मैं वहां कैसे पहुंचा')

हालाँकि, अब उन निजी कार्यों को सीधे यूनिट-टेस्ट करना आसान लगता है , और बड़े सार्वजनिक फ़ंक्शन के परीक्षण को कुछ प्रकार के 'एकीकरण' परीक्षण के लिए छोड़ देते हैं जहां एक परिदृश्य को संबोधित करने की आवश्यकता होती है।

बस मेरे 2 सेंट।


2
@jop पर प्रतिक्रिया करने के लिए, मुझे उन निजी कार्यों को निर्यात करने की आवश्यकता महसूस नहीं होती है (जो एक बड़े वर्ग के जटिल सार्वजनिक कार्य के विभाजन के कारण निर्मित)। मैं उन्हें अभी भी सार्वजनिक रूप से एक ही वर्ग में कसकर युग्मित करना पसंद करता हूं। लेकिन फिर भी यूनिट-परीक्षण किया गया।
वॉन सी सी

2
मेरा अनुभव यह है कि वे निजी विधियाँ केवल उपयोगिता पद्धति हैं जो उन सार्वजनिक विधियों द्वारा पुन: उपयोग की जा रही हैं। कभी-कभी मूल कक्षा को दो (या तीन) अधिक सुसंगत वर्गों में विभाजित करना अधिक सुविधाजनक होता है, जिससे उन निजी तरीकों को अपनी कक्षाओं में सार्वजनिक किया जा सकता है, और इसलिए परीक्षण योग्य होता है।
जप

7
नहींं, मेरे मामले में, वे नए निजी कार्य वास्तव में सार्वजनिक फ़ंक्शन द्वारा दर्शाए गए बड़े एल्गोरिदम का हिस्सा हैं। उस फ़ंक्शन को छोटे भागों में विभाजित किया गया है, जो उपयोगिता नहीं है, लेकिन एक बड़ी प्रक्रिया के चरण हैं। इसलिए उन्हें यूनिट-टेस्ट करने की आवश्यकता है (यूनिट-टेस्ट के बजाय एक बार में पूरे एलो-टेस्ट)
वॉन सी सी

चक्रवाती जटिलता में रुचि रखने वालों के लिए, मैंने इस विषय पर एक प्रश्न जोड़ा: stackoverflow.com/questions/105852/…
VonC

ओह, शीर्षक में एक टाइपो के कारण प्रश्न का यूआरएल बदल गया! stackoverflow.com/questions/105852/…
VONC

51

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

हमारे पास निजी तरीके क्यों हैं?

निजी कार्य मुख्य रूप से हमारी कक्षा में मौजूद हैं क्योंकि हम अपने सार्वजनिक तरीकों से पठनीय कोड बनाना चाहते हैं। हम नहीं चाहते कि इस वर्ग के उपयोगकर्ता इन विधियों को सीधे कॉल करें, लेकिन हमारे सार्वजनिक तरीकों के माध्यम से। साथ ही, हम क्लास को बढ़ाते समय (संरक्षित होने की स्थिति में) उनके व्यवहार को बदलना नहीं चाहते हैं, इसलिए यह एक निजी है।

जब हम कोड करते हैं, तो हम परीक्षण-संचालित-डिजाइन (TDD) का उपयोग करते हैं। इसका मतलब है कि कभी-कभी हम कार्यक्षमता के एक टुकड़े पर ठोकर खाते हैं जो निजी है और परीक्षण करना चाहते हैं। निजी कार्य phpUnit में परीक्षण करने योग्य नहीं हैं, क्योंकि हम उन्हें टेस्ट क्लास (वे निजी हैं) में प्रवेश नहीं कर सकते हैं।

हमें लगता है कि यहाँ 3 समाधान हैं:

1. आप अपने निजी तरीकों का अपने सार्वजनिक तरीकों से परीक्षण कर सकते हैं

लाभ

  • सीधी इकाई परीक्षण ('हैक' की आवश्यकता नहीं)

नुकसान

  • प्रोग्रामर को सार्वजनिक विधि को समझने की आवश्यकता है, जबकि वह केवल निजी पद्धति का परीक्षण करना चाहता है
  • आप अनुप्रयोग के सबसे छोटे परीक्षण योग्य भाग का परीक्षण नहीं कर रहे हैं

2. यदि निजी इतना महत्वपूर्ण है, तो हो सकता है कि यह उसके लिए एक नया अलग वर्ग बनाने के लिए एक कोडस्मेल हो

लाभ

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

नुकसान

  • यदि आप की आवश्यकता नहीं है, तो आप एक वर्ग बनाना नहीं चाहते हैं, और केवल उस वर्ग द्वारा उपयोग किया जाता है जहां विधि आ रही है
  • अतिरिक्त उपरि के कारण संभावित प्रदर्शन हानि

3. एक्सेस मोडिफायर को (फाइनल) प्रोटेक्ट में बदलें

लाभ

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

नुकसान

  • आप संरक्षित करने के लिए एक निजी पहुंच बदल रहे हैं, जिसका अर्थ है कि यह बच्चों द्वारा सुलभ है
  • इसका उपयोग करने के लिए आपको अभी भी अपने परीक्षण वर्ग में मॉक क्लास की आवश्यकता है

उदाहरण

class Detective {
  public function investigate() {}
  private function sleepWithSuspect($suspect) {}
}
Altered version:
class Detective {
  public function investigate() {}
  final protected function sleepWithSuspect($suspect) {}
}
In Test class:
class Mock_Detective extends Detective {

  public test_sleepWithSuspect($suspect) 
  {
    //this is now accessible, but still not overridable!
    $this->sleepWithSuspect($suspect);
  }
}

इसलिए हमारी परीक्षण इकाई अब हमारे पूर्व निजी फ़ंक्शन का परीक्षण करने के लिए test_sleepWithSuspect को कॉल कर सकती है।


eddy147, मुझे वास्तव में मॉक के माध्यम से संरक्षित विधियों के परीक्षण की अवधारणा पसंद है। धन्यवाद!!!!
थियोडोर आर। स्मिथ

15
मैं तो बस करते रहे कि TDD के मूल वर्णन में, इकाई परीक्षण में, चाहते इकाई है वर्ग , नहीं एक विधि / समारोह। इसलिए जब आप "एप्लिकेशन के सबसे छोटे हिस्से का परीक्षण" का उल्लेख करते हैं , तो एक विधि के रूप में सबसे छोटे परीक्षण योग्य भाग को संदर्भित करना गलत है। यदि आप उस तर्क का उपयोग करते हैं, तो आप एक पूरे कोड ब्लॉक के बजाय कोड की एक पंक्ति पर बात कर सकते हैं।
मैट क्विगले

@ काम की एक इकाई एक वर्ग को इंगित कर सकती है, लेकिन एक एकल विधि भी है।
eddy147

4
@ eddy147 यूनिट परीक्षण में टेस्ट ड्रिवेन डेवलपमेंट आता है, जहाँ यूनिट को एक वर्ग के रूप में परिभाषित किया गया था। जैसा कि द इन्टर्नेट्स के साथ होता है, शब्दार्थ का विस्तार बहुत सारी चीजों के लिए हुआ है (अर्थात 2 लोगों से पूछें कि इकाई और एकीकरण परीक्षण में क्या अंतर है, और आपको 7 उत्तर मिलेंगे)। TDD का अर्थ था, SOLID सिद्धांतों के साथ सॉफ्टवेयर लिखने का एक तरीका, जिसमें सिंगल रिस्पांसिबिलिटी भी शामिल है, जहाँ एक क्लास की एक ही ज़िम्मेदारी थी और एक उच्च चक्रीय जटिलता नहीं होनी चाहिए। TDD में, आप अपनी क्लास को लिखते हैं और एक साथ दोनों यूनिट को टेस्ट करते हैं। निजी तरीकों encapsulated हैं एक इसी इकाई परीक्षण नहीं है।
मैट क्विग्ले 19

"जब हम कोड करते हैं, तो हम परीक्षण-संचालित-डिजाइन (TDD) का उपयोग करते हैं। इसका मतलब है कि कभी-कभी हम कार्यक्षमता के एक टुकड़े पर ठोकर खाते हैं जो निजी है और परीक्षण करना चाहते हैं।" मैं इस कथन से पूरी तरह असहमत हूं, कृपया नीचे दिए गए मेरे जवाब को और विस्तार से देखें। टीडीडी का मतलब यह नहीं है कि आप निजी तरीकों का परीक्षण करने के लिए मजबूर हैं। आप निजी तरीकों का परीक्षण करने का विकल्प चुन सकते हैं: और यह आपकी पसंद है, लेकिन यह टीडीडी नहीं है जो आपको ऐसा काम करने के लिए तैयार कर रहा है।
मैट मेसमिथिथ

41

मुझे कुछ कारणों से निजी कार्यक्षमता का परीक्षण करना पसंद नहीं है। वे इस प्रकार हैं (ये TLDR लोगों के लिए मुख्य बिंदु हैं):

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

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

कई बार निजी तरीकों का परीक्षण करना उचित है, ऊपर सूचीबद्ध डाउनसाइड्स के बारे में पता होना बहुत जरूरी है। मैं बाद में इसे और अधिक विस्तार से बताने जा रहा हूं।

मैं यह भी बताता हूं कि बहुत अंत में टीडीडी निजी तरीकों के परीक्षण के लिए एक वैध बहाना क्यों नहीं है।

ख़राब डिज़ाइन से अपना रास्ता निकाल कर

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

नियम का मूल्यांकन करनेवाला

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

TEST_THAT(RuleEvaluator, canParseSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    re = RuleEvaluator(input_string);

    ASSERT re.GetNextToken() IS "1";
    ASSERT re.GetNextToken() IS "2";
    ASSERT re.GetNextToken() IS "test";
    ASSERT re.GetNextToken() IS "bar";
    ASSERT re.HasMoreTokens() IS FALSE;
}

खैर, यह वास्तव में बहुत अच्छा लग रहा है। हम यह सुनिश्चित करना चाहते हैं कि जैसे-जैसे हम परिवर्तन करते हैं, हम इस व्यवहार को बनाए रखें। लेकिन GetNextToken()एक निजी समारोह है! इसलिए हम इसे इस तरह से नहीं परख सकते हैं, क्योंकि यह भी संकलन नहीं करता है (यह मानते हुए कि हम कुछ भाषा का उपयोग कर रहे हैं जो वास्तव में सार्वजनिक / निजी को लागू करता है, कुछ स्क्रिप्टिंग भाषाओं जैसे पाइथन के विपरीत)। लेकिन RuleEvaluatorएकल जिम्मेदारी सिद्धांत (एकल जिम्मेदारी सिद्धांत) का पालन करने के लिए कक्षा को बदलने के बारे में क्या ? उदाहरण के लिए, हमें एक पार्सर, टोकनधारक और मूल्यांकनकर्ता एक वर्ग में जाम लगता है। क्या उन जिम्मेदारियों को अलग करना बेहतर नहीं होगा? उसके ऊपर, यदि आप बनाते हैंTokenizer वर्ग , तो यह सार्वजनिक तरीके हैं HasMoreTokens()और GetNextTokens()RuleEvaluatorवर्ग एक हो सकता थाTokenizerएक सदस्य के रूप में वस्तु। अब, हम ऊपर के समान परीक्षण रख सकते हैं, सिवाय इसके कि हम Tokenizerकक्षा के बजाय कक्षा का परीक्षण कर रहे हैं RuleEvaluator

यहाँ यह UML में कैसा दिख सकता है:

नियम का मूल्यांकन करने वाला

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

परीक्षा बेहद समान दिखाई देगी, सिवाय इसके कि वास्तव में इस बार संकलन होगा क्योंकि GetNextToken()विधि अब Tokenizerकक्षा में सार्वजनिक है :

TEST_THAT(Tokenizer, canParseSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    tokenizer = Tokenizer(input_string);

    ASSERT tokenizer.GetNextToken() IS "1";
    ASSERT tokenizer.GetNextToken() IS "2";
    ASSERT tokenizer.GetNextToken() IS "test";
    ASSERT tokenizer.GetNextToken() IS "bar";
    ASSERT tokenizer.HasMoreTokens() IS FALSE;
}

सार्वजनिक इंटरफ़ेस के माध्यम से निजी घटकों का परीक्षण करना और परीक्षण दोहराव से बचना

यहां तक ​​कि अगर आपको नहीं लगता है कि आप अपनी समस्या को कम मॉड्यूलर घटकों (जो आप 95% समय पर कर सकते हैं यदि आप इसे करने की कोशिश करते हैं) में तोड़ सकते हैं , तो आप बस एक सार्वजनिक इंटरफ़ेस के माध्यम से निजी कार्यों का परीक्षण कर सकते हैं। कई बार निजी सदस्य परीक्षण के लायक नहीं होते क्योंकि उनका परीक्षण सार्वजनिक इंटरफ़ेस के माध्यम से किया जाएगा। बहुत बार जो मैं देखता हूं, वह परीक्षण है जो बहुत लगते हैं समान , लेकिन दो अलग-अलग कार्यों / विधियों का परीक्षण करते हैं। क्या हो रहा समाप्त होता है कि जब आवश्यकताओं परिवर्तन (और वे हमेशा करते हैं), तो आप अब 2 टूट परीक्षण 1. के बजाय और अगर आप वास्तव में आपकी सभी निजी तरीकों का परीक्षण किया है, तो आप 1. के बजाय और अधिक की तरह 10 टूट परीक्षण हो सकता है है संक्षेप में , निजी कार्यों का परीक्षण (उपयोग करके)FRIEND_TESTया उन्हें सार्वजनिक या परावर्तन का उपयोग करते हुए) जिसे अन्यथा एक सार्वजनिक इंटरफ़ेस के माध्यम से परीक्षण किया जा सकता है, परीक्षण दोहराव का कारण बन सकता है । आप वास्तव में यह नहीं चाहते हैं, क्योंकि आपके टेस्ट सूट से अधिक कुछ भी आपको धीमा नहीं करता है। यह विकास के समय को कम करने और रखरखाव की लागत को कम करने वाला है! यदि आप निजी तरीकों का परीक्षण करते हैं जो अन्यथा एक सार्वजनिक इंटरफ़ेस के माध्यम से परीक्षण किया जाता है, तो परीक्षण सूट बहुत अच्छी तरह से विपरीत कर सकता है, और सक्रिय रूप से रखरखाव की लागत में वृद्धि और विकास के समय को बढ़ा सकता है। जब आप किसी निजी फ़ंक्शन को सार्वजनिक करते हैं, या यदि आप कुछ FRIEND_TESTऔर / या प्रतिबिंब का उपयोग करते हैं , तो आप आमतौर पर इसे लंबे समय में पछतावा करेंगे।

Tokenizerकक्षा के निम्नलिखित संभावित कार्यान्वयन पर विचार करें :

यहां छवि विवरण दर्ज करें

मान लीजिए कि SplitUpByDelimiter()एक सरणी को वापस करने के लिए ज़िम्मेदार है जैसे कि सरणी में प्रत्येक तत्व एक टोकन है। इसके अलावा, चलो बस कहना है कि GetNextToken()इस वेक्टर पर बस एक पुनरावृत्ति है। तो आपका सार्वजनिक परीक्षण यह देख सकता है:

TEST_THAT(Tokenizer, canParseSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    tokenizer = Tokenizer(input_string);

    ASSERT tokenizer.GetNextToken() IS "1";
    ASSERT tokenizer.GetNextToken() IS "2";
    ASSERT tokenizer.GetNextToken() IS "test";
    ASSERT tokenizer.GetNextToken() IS "bar";
    ASSERT tokenizer.HasMoreTokens() IS false;
}

आइए दिखाते हैं कि हमारे पास माइकल फेदर का ग्रोपिंग टूल क्या है । यह एक उपकरण है जो आपको अन्य लोगों के निजी भागों को छूने देता है। एक उदाहरण FRIEND_TESTगूगलेट से है, या प्रतिबिंब यदि भाषा इसका समर्थन करती है।

TEST_THAT(TokenizerTest, canGenerateSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    tokenizer = Tokenizer(input_string);
    result_array = tokenizer.SplitUpByDelimiter(" ");

    ASSERT result.size() IS 4;
    ASSERT result[0] IS "1";
    ASSERT result[1] IS "2";
    ASSERT result[2] IS "test";
    ASSERT result[3] IS "bar";
}

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

निजी तरीकों का परीक्षण कब उचित हो सकता है?

सॉफ्टवेयर में कोई "एक आकार सभी फिट बैठता है" नहीं है। कभी-कभी "नियमों को तोड़ने" के लिए यह ठीक है (और वास्तव में आदर्श)। जब आप कर सकते हैं तो मैं निजी कार्यक्षमता का परीक्षण नहीं करने की दृढ़ता से वकालत करता हूं। जब मुझे लगता है कि यह ठीक है तो दो मुख्य परिस्थितियां हैं:

  1. मैंने विरासत प्रणालियों के साथ बड़े पैमाने पर काम किया है (यही वजह है कि मैं इतना बड़ा माइकल फेदर प्रशंसक हूं), और मैं सुरक्षित रूप से कह सकता हूं कि कभी-कभी यह सिर्फ निजी कार्यक्षमता का परीक्षण करने के लिए सबसे सुरक्षित है। यह बेसलाइन में "चरित्रांकन परीक्षण" प्राप्त करने के लिए विशेष रूप से सहायक हो सकता है।

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

वहाँ शायद अन्य स्थितियों जहाँ यह ठीक है। अगर आपको लगता है कि यह ठीक है, और आपके पास एक अच्छा औचित्य है, तो इसे करें। कोई आपको रोक नहीं रहा है। बस संभावित लागतों के बारे में पता होना चाहिए।

TDD बहाना

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

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

ध्यान दें:

मैंने थोड़ी देर पहले GoogleTest का उपयोग करके निजी तरीकों के परीक्षण के बारे में इसी तरह के सवाल का जवाब दिया । मैंने ज्यादातर संशोधित किया है कि यहाँ अधिक भाषा अज्ञेय होने का जवाब है।

PS यहाँ माइकल पंखों द्वारा आइसबर्ग कक्षाओं और ग्रोपिंग टूल के बारे में प्रासंगिक व्याख्यान दिया गया है: https://www.youtube.com/watch?v=4cVZvoFGJTU


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

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

26

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

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


21

यदि आपके सार्वजनिक तरीकों को कॉल करके आपकी निजी पद्धति का परीक्षण नहीं किया जाता है तो यह क्या कर रहा है? मैं निजी बात कर रहा हूँ संरक्षित या मित्र नहीं।


3
धन्यवाद। यह आश्चर्यजनक रूप से रेखांकित टिप्पणी है और विशेष रूप से अभी भी प्रासंगिक है, लगभग 8 वर्षों के बाद भी इसे लिखा गया था।
सौरोनलॉर्ड

1
एक ही तर्क के साथ एक उपयोगकर्ता इंटरफ़ेस (सिस्टम स्तर परीक्षण) से केवल सॉफ्टवेयर का परीक्षण करने का तर्क दे सकता है, क्योंकि सॉफ्टवेयर में हर फ़ंक्शन को किसी भी तरह से वहाँ से निष्पादित किया जाएगा।
डिर्क हेरमैन

18

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

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

यह बाद में डीबगिंग को गति देता है।

-Adam


1
इस मामले में, उस निजी पद्धति को किसी अन्य वर्ग में स्थानांतरित करने का कोई मतलब नहीं होगा, तो बस इसे सार्वजनिक या सार्वजनिक स्थैतिक बनाएं?
आउटलाव प्रोग्रामर

+1 यदि आप अपने निजी सदस्य कार्यों का परीक्षण नहीं करते हैं और सार्वजनिक इंटरफ़ेस का आपका परीक्षण विफल हो जाता है, तो आपको यह परिणाम मिलेगा कि किसी चीज़ के बराबर कुछ बिना किसी विचार के टूट गया है।
ओलुमाइड

12

यदि आप परीक्षण संचालित (TDD) विकसित कर रहे हैं, तो आप अपने निजी तरीकों का परीक्षण करेंगे।



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

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

असहमत, मेरा जवाब नीचे देखें
मैट मेसमेरिथ

11

मैं इस क्षेत्र का विशेषज्ञ नहीं हूं, लेकिन इकाई परीक्षण को व्यवहार का परीक्षण करना चाहिए, कार्यान्वयन का नहीं। निजी विधियाँ सख्ती से कार्यान्वयन का हिस्सा हैं, इसलिए IMHO का परीक्षण नहीं किया जाना चाहिए।


कार्यान्वयन कहाँ है तब परीक्षण किया गया? यदि कुछ कार्यक्षमता कैशिंग का उपयोग करती है, तो क्या यह एक कार्यान्वयन विवरण है और कैशिंग का परीक्षण नहीं किया गया है?
डिर्क हेरमैन

11

हम निजी तरीकों का परीक्षण करते हैं, जिसके द्वारा मेरा मतलब है कि हम कम से कम 95% की कुल श्रेणी परीक्षण कवरेज की तलाश करते हैं, लेकिन केवल हमारे परीक्षण सार्वजनिक या आंतरिक तरीकों से कॉल करते हैं। कवरेज प्राप्त करने के लिए, हमें विभिन्न परिदृश्यों के आधार पर जनता / आंतरिक लोगों को कई कॉल करने की आवश्यकता हो सकती है। यह हमारे परीक्षणों को उस कोड के उद्देश्य के आसपास अधिक इरादतन बनाता है जो वे परीक्षण कर रहे हैं।

आपके द्वारा पोस्ट किए गए ट्रम्प का जवाब सबसे अच्छा है।


9

मेरा मानना ​​है कि यूनिट परीक्षण सार्वजनिक तरीकों के परीक्षण के लिए हैं। आपकी सार्वजनिक विधियां आपके निजी तरीकों का उपयोग करती हैं, इसलिए अप्रत्यक्ष रूप से वे भी परीक्षण कर रहे हैं।


7

मैं इस मुद्दे पर कुछ समय के लिए टीडीडी पर अपना हाथ आजमाने के साथ कुछ समय के लिए रहा हूँ।

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

  1. निजी तरीकों का परीक्षण, टीडीडी और टेस्ट-ड्रिवेन रीफैक्टरिंग
  2. परीक्षण-संचालित विकास परीक्षण नहीं है

संक्षेप में:

  • परीक्षण संचालित विकास (डिजाइन) तकनीकों का उपयोग करते समय, निजी तरीकों को पहले से ही काम कर रहे और परीक्षण किए गए कोड की पुन: फैक्टरिंग प्रक्रिया के दौरान ही उत्पन्न होना चाहिए।

  • प्रक्रिया की प्रकृति से, किसी भी सरल परीक्षण कार्य से निकाले गए सरल कार्यान्वयन कार्यक्षमता में से किसी एक को स्व-परीक्षण किया जाएगा (यानी अप्रत्यक्ष परीक्षण कवरेज)।

मेरे लिए यह पर्याप्त स्पष्ट है कि कोडिंग की शुरुआत में अधिकांश तरीके उच्च स्तर के कार्य होंगे क्योंकि वे डिजाइन को इनकैप्सुलेट / वर्णन कर रहे हैं।

इसलिए, ये विधियां सार्वजनिक होंगी और उनका परीक्षण करना काफी आसान होगा।

निजी तरीके बाद में आएंगे जब सबकुछ ठीक हो जाएगा और हम पठनीयता और स्वच्छता की खातिर फिर से आ रहे हैं ।


6

जैसा कि ऊपर कहा गया है, "यदि आप अपने निजी तरीकों का परीक्षण नहीं करते हैं, तो आपको कैसे पता चलेगा कि वे नहीं टूटेंगे?"

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

मैंने ऐसा करने के लिए सबसे अच्छे तरीकों में से एक पाया है कि बस परियोजना के लिए परीक्षण संदर्भ जोड़ें और परीक्षणों को निजी तरीकों के समानांतर एक कक्षा में रखें। उपयुक्त बिल्ड लॉजिक में रखें ताकि परीक्षण अंतिम प्रोजेक्ट में न बनें।

फिर आपके पास इन तरीकों का परीक्षण करने के सभी लाभ हैं और आप सेकंड बनाम मिनट या घंटों में समस्या पा सकते हैं।

इसलिए सारांश में, हाँ, इकाई आपके निजी तरीकों का परीक्षण करती है।


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

6

आपको नहीं करना चाहिए । यदि आपके निजी तरीकों में पर्याप्त जटिलता है जिसका परीक्षण किया जाना चाहिए, तो आपको उन्हें दूसरे वर्ग पर रखना चाहिए। उच्च सामंजस्य रखें , एक वर्ग का केवल एक उद्देश्य होना चाहिए। वर्ग सार्वजनिक इंटरफ़ेस पर्याप्त होना चाहिए।


3

यदि आप अपने निजी तरीकों का परीक्षण नहीं करते हैं, तो आप कैसे जानते हैं कि वे नहीं टूटेंगे?


19
अपने सार्वजनिक तरीकों के परीक्षणों के माध्यम से लिखकर।
scubabbl

3
उन निजी तरीकों को निश्चित रूप से वर्ग के सार्वजनिक तरीकों से कहा जाता है। तो बस उन सार्वजनिक तरीकों का परीक्षण करें जो निजी तरीकों को कहते हैं।
19:00

1
यदि आपके सार्वजनिक तरीके ठीक से काम कर रहे हैं, तो जाहिर है कि जिस निजी तरीके से वे काम कर रहे हैं वह ठीक से काम कर रहा है।
17 की 26

यदि आपके सार्वजनिक तरीकों के परीक्षण विफल हो जाते हैं, तो आप तुरंत जानते हैं कि आपके ऑब्जेक्ट / घटक / आदि में निचले स्तर पर कुछ सही नहीं है।
रोब

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

2

यह स्पष्ट रूप से भाषा पर निर्भर है। सी ++ के साथ अतीत में, मैंने परीक्षण वर्ग को मित्र वर्ग घोषित किया है। दुर्भाग्यवश, परीक्षण वर्ग के बारे में जानने के लिए आपके उत्पादन कोड की आवश्यकता होती है।


5
मित्र कीवर्ड मुझे दुखी करता है।
रोब

यह समस्या नहीं है यदि परीक्षण वर्ग को किसी अन्य प्रोजेक्ट में लागू किया गया है। यह महत्वपूर्ण है कि उत्पादन कोड परीक्षण वर्ग को संदर्भित नहीं करता है।
ओलुमाइड

2

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

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

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

मेरे लिए निजी और सार्वजनिक तरीकों के बीच सीमा एक मनोवैज्ञानिक मानदंड है जब यह परीक्षण की बात आती है। मानदंड जो मेरे लिए अधिक मायने रखते हैं:

  • विधि को विभिन्न स्थानों से एक से अधिक बार कहा जाता है?
  • परीक्षण की आवश्यकता के लिए विधि पर्याप्त परिष्कृत है?

1

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


1

मैं यूनिट टेस्ट की अवधारणा को कभी नहीं समझता लेकिन अब मुझे पता है कि इसका उद्देश्य क्या है।

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

एक इकाई परीक्षण अधिक धुरी परीक्षण है आप कुछ मनमानी धुरी को चिह्नित करते हैं और धुरी का परिणाम समान रहना चाहिए।


1

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

क्या मायने रखता है कवरेज और लागत। आपको अपनी परियोजना (लाइन, शाखा, पथ, ब्लॉक, विधि, वर्ग, समतुल्यता वर्ग, उपयोग-मामला ... जो भी टीम तय करती है) के कवरेज लक्ष्यों को प्राप्त करते समय लागत को कम करने की आवश्यकता है।

इसलिए कवरेज सुनिश्चित करने के लिए उपकरणों का उपयोग करें, और कम से कम लागत (अल्पकालिक और दीर्घकालिक ) के लिए अपने परीक्षणों को डिज़ाइन करें ।

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

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


0

यदि विधि पर्याप्त रूप से पर्याप्त / जटिल है, तो मैं आमतौर पर इसे "संरक्षित" बनाऊंगा और इसका परीक्षण करूंगा। कुछ विधियों को सार्वजनिक / संरक्षित विधियों के लिए यूनिट परीक्षणों के भाग के रूप में निजी रूप से छोड़ दिया जाएगा और इसका परीक्षण किया जाएगा।


1
@VoiceForTesting उसके लिए एक एनोटेशन है। मैं परीक्षण के लिए एनकैप्सुलेशन को शिथिल नहीं करूंगा, बल्कि dp4j.com का उपयोग करें
simpatico

0

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


वर्तमान प्रवृत्ति को कम करने या कोई क्यूए टीम नहीं है। ये इकाई परीक्षण स्वचालित परीक्षण बन जाते हैं जो हर बार एक इंजीनियर मास्टर शाखा पर कोड को धक्का देते हैं। यहां तक ​​कि क्यूए के साथ, कोई तरीका नहीं है कि वे पूरे एप्लिकेशन को स्वचालित परीक्षणों के रूप में तेजी से परीक्षण कर सकें।
पैट्रिक डेसजार्डिन्स

0

"क्या मुझे निजी तरीकों का परीक्षण करना चाहिए?" कभी कभी है"। आमतौर पर आपको अपनी कक्षाओं के इंटरफेस के खिलाफ परीक्षण करना चाहिए।

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

यहाँ एक उदाहरण है:

class Thing
  def some_string
    one + two
  end

  private 

  def one
    'aaaa'
  end

  def two
    'bbbb'
  end

end


class RefactoredThing
def some_string
    one + one_a + two + two_b
  end

  private 

  def one
    'aa'
  end

  def one_a
    'aa'
  end

  def two
    'bb'
  end

  def two_b
    'bb'
  end
end

में RefactoredThingआप अब 5 परीक्षण, जिनमें से 2 आप पुनर्रचना के लिए अद्यतन करने के लिए किया था है, लेकिन अपने वस्तु की कार्यक्षमता वास्तव में नहीं बदला है। तो चलिए बताते हैं कि चीजें इससे ज्यादा जटिल हैं और आपके पास कुछ तरीका है जो आउटपुट के क्रम को परिभाषित करता है जैसे:

def some_string_positioner
  if some case
  elsif other case
  elsif other case
  elsif other case
  else one more case
  end
end

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

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


0

नहीं, आपको निजी तरीकों का परीक्षण क्यों नहीं करना चाहिए ? और मॉकिटो जैसे लोकप्रिय मॉकिंग ढांचे को निजी तरीकों के परीक्षण के लिए समर्थन प्रदान नहीं करता है।


0

एक मुख्य बिंदु है

यदि हम तर्क की शुद्धता सुनिश्चित करने के लिए परीक्षण करते हैं, और एक निजी पद्धति एक तर्क ले जा रही है, तो हमें इसका परीक्षण करना चाहिए। है ना? तो हम इसे क्यों छोड़ रहे हैं?

तरीकों की दृश्यता के आधार पर परीक्षण लिखना पूरी तरह से अप्रासंगिक विचार है।

इसके विपरीत

दूसरी ओर, मूल कक्षा के बाहर एक निजी पद्धति को कॉल करना एक मुख्य समस्या है। और कुछ नकली साधनों में एक निजी विधि का मजाक उड़ाने की भी सीमाएँ हैं। (पूर्व: मॉकिटो )

हालांकि कुछ उपकरण हैं जैसे पावर मॉक जो इसका समर्थन करते हैं, यह एक खतरनाक ऑपरेशन है। इसका कारण इसे हासिल करने के लिए जेवीएम को हैक करना है।

चारों ओर एक काम किया जा सकता है (यदि आप निजी तरीकों के लिए परीक्षण के मामले लिखना चाहते हैं)

उन निजी तरीकों को संरक्षित घोषित करें । लेकिन यह कई स्थितियों के लिए सुविधाजनक नहीं हो सकता है।


0

यह केवल सार्वजनिक या निजी तरीकों या कार्यों के बारे में नहीं है, यह कार्यान्वयन विवरण के बारे में है। निजी कार्य कार्यान्वयन विवरण का सिर्फ एक पहलू है।

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

ए) हां, आपको कार्यान्वयन विवरण का परीक्षण करना चाहिए:

एक सॉर्ट फ़ंक्शन के बारे में सोचें, जो प्रदर्शन कारणों से 10 तत्वों तक का है, तो बबलसॉर्ट का एक निजी कार्यान्वयन का उपयोग करता है, और 10 से अधिक तत्वों के होने पर एक अलग प्रकार के दृष्टिकोण (जैसे, हेप्सोर्ट) का एक निजी कार्यान्वयन। सार्वजनिक एपीआई एक प्रकार का कार्य है। आपका परीक्षण सूट, हालांकि, बेहतर ज्ञान का उपयोग करता है कि वास्तव में दो प्रकार के एल्गोरिदम का उपयोग किया जाता है।

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

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

बी) कार्यान्वयन विवरण का परीक्षण कैसे करें

एक कारण है कि बहुत से लोग तर्क देते हैं कि किसी को निजी कार्यों का परीक्षण नहीं करना चाहिए या कार्यान्वयन विवरण नहीं है, कि कार्यान्वयन के विवरण में परिवर्तन की संभावना है। कम से कम परिवर्तन की यह उच्च संभावना इंटरफेस के पीछे कार्यान्वयन विवरण को छिपाने के कारणों में से एक है।

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

यह दिलचस्प है: जबकि इंटरफ़ेस आंतरिक था, एक कार्यान्वयन विवरण होने के नाते, इसे बदलने की संभावना थी। समान इंटरफ़ेस लेना, इसे सार्वजनिक करना कुछ जादू परिवर्तन करता है, अर्थात् इसे एक ऐसे इंटरफ़ेस में बदलना जो बदलने की संभावना कम है। जाहिर है कि इस तर्क में कुछ खामी है।

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

फिर भी, "फ्रंट डोर फर्स्ट" का उपयोग करना अंगूठे का एक अच्छा नियम है (देखें http://xunitpatterns.com/Principles%20of%20Test%20Automation.html ) । लेकिन ध्यान रखें कि इसे "फ्रंट डोर फर्स्ट" कहा जाता है न कि केवल "फ्रंट डोर"।

ग) सारांश

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


0

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

निम्नलिखित थोड़ा वंचित उदाहरण पर विचार करें। मान लीजिए कि हम सार्वजनिक रूप से एक फ़ंक्शन को उजागर करना चाहते हैं जो 3 पूर्णांक लेता है और यह सच है कि अगर और केवल उन 3 पूर्णांक सभी प्रमुख हैं। हम इसे इस तरह लागू कर सकते हैं:

public bool allPrime(int a, int b, int c)
{
  return andAll(isPrime(a), isPrime(b), isPrime(c))
}

private bool andAll(bool... boolArray)
{
  foreach (bool b in boolArray)
  {
    if(b == false) return false;
  }
  return true;
}

private bool isPrime(int x){
  //Implementation to go here. Sorry if you were expecting a prime sieve.
}

अब, अगर हमें यह सख्त तरीका अपनाना था कि केवल सार्वजनिक कार्यों का परीक्षण किया जाए, तो हमें केवल परीक्षण करने की अनुमति होगी या allPrimeनहीं ।isPrimeandAll

एक परीक्षक के रूप में, हम एक तर्क के लिए पांच संभावनाओं में रुचि हो सकती: < 0, = 0, = 1, prime > 1, not prime > 1। लेकिन पूरी तरह से, हमें यह भी देखना होगा कि तर्कों का हर संयोजन एक साथ कैसे चलता है। तो यह 5*5*5= 125 परीक्षण के मामले हमें अपने अंतर्ज्ञान के अनुसार इस फ़ंक्शन का पूरी तरह से परीक्षण करने की आवश्यकता होगी।

दूसरी ओर, यदि हमें निजी कार्यों का परीक्षण करने की अनुमति दी गई है, तो हम कम परीक्षण मामलों के साथ अधिक जमीन को कवर कर सकते हैं। हमें isPrimeअपने पिछले अंतर्ज्ञान के समान स्तर पर परीक्षण करने के लिए केवल 5 परीक्षण मामलों की आवश्यकता होगी । और डैनियल जैक्सन द्वारा प्रस्तावित छोटे दायरे की परिकल्पना के अनुसार, हमें केवल andAll3 या 4 की लंबाई तक फ़ंक्शन का परीक्षण करना होगा। जो कि अधिक से अधिक 16 परीक्षणों में होगा। तो कुल 21 परीक्षण। 125 के बजाय। बेशक, हम शायद कुछ परीक्षण चलाना चाहते हैंallPrime , लेकिन हमें ऐसा नहीं लगेगा कि हमने इनपुट परिदृश्यों के सभी 125 संयोजनों को कवर करने के लिए बाध्य किया है। बस कुछ खुश रास्ते।

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


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

मैट हाँ उदाहरण आदर्श नहीं है मैं आपको दे दूँगा। लेकिन सिद्धांत स्पष्ट होना चाहिए।
कॉलम भंडाल

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

0

आप अपने तरीके को पैकेज-प्राइवेट यानी डिफॉल्ट भी बना सकते हैं और जब तक निजी होना जरूरी नहीं है तब तक आप इसे टेस्ट कर सकते हैं।

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