यूनिट टेस्ट निजी तरीकों की आवश्यकता से कैसे बचें


15

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

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

मैं निजी तौर पर लोगों का परीक्षण करते समय और निजी लोगों का परीक्षण करते समय बाहरी निर्भरता का मजाक उड़ाते हुए निजी तरीकों का मजाक उड़ाना पसंद करता हूं।

मैं पागल हो रहा हूँ?


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

जवाबों:


24

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

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

व्यक्तिगत रूप से, मैं यूनिट परीक्षणों के लिए एक सफेद-बॉक्स दृष्टिकोण पसंद करता हूं। मैं विभिन्न राज्यों में परीक्षण के तरीकों और कक्षाओं को लगाने के लिए परीक्षण कर सकता हूं जो मेरे सार्वजनिक और निजी तरीकों में दिलचस्प व्यवहार का कारण बनता है और फिर यह दावा करता है कि परिणाम वही हैं जो मैं उम्मीद करता हूं।

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


1
"अपने निजी तरीकों का मज़ाक न उड़ाएं" हाँ, मैं परीक्षण को समझ सकता हूं, जब आप उनका मजाक उड़ा रहे हों तो आप ठीक महीन रेखा को पार करने के लिए पागल हो सकते हैं
इवान

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

8
@FranSevillano यदि आपको बहुत अधिक स्टब या मॉक करना है, तो मैं आपके समग्र डिजाइन को देखूंगा। कुछ महसूस होता है।
थॉमस ओवेन्स

एक कोड कवरेज टूल इससे मदद करता है।
एंडी

5
@FranSevillano: एक वर्ग के लिए कई अच्छे कारण नहीं हैं जो निर्भरता के टन करने के लिए एक काम करता है। यदि आपके पास कई निर्भरताएं हैं, तो संभवतः आपके पास एक ईश्वर वर्ग है।
मूइंग डक

4

मुझे लगता है कि यह बहुत घटिया विचार है।

निजी सदस्यों के इकाई परीक्षण बनाने में समस्या यह है कि यह उत्पाद जीवनचक्र के साथ खराब बैठता है।

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

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

मेरा तुम्हें सुझाव है:

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

इस कार्यक्षमता का परीक्षण करने के लिए आपके झुकाव की सराहना करते हैं और यह कि इसे आपके वर्तमान सार्वजनिक एपीआई के माध्यम से जांचना कठिन है। लेकिन मैं व्यक्तिगत रूप से परीक्षण कवरेज से अधिक मॉड्यूलरिटी को महत्व देता हूं।


6
मैं असहमत हूं। IMO, यह एकीकरण परीक्षणों के लिए 100% सही है। लेकिन यूनिट परीक्षणों के साथ चीजें अलग हैं; इकाई परीक्षण का लक्ष्य यह इंगित करना है कि एक बग कहां है, पर्याप्त संकीर्ण है ताकि आप इसे जल्दी से ठीक कर सकें। मैं खुद को अक्सर इस स्थिति में पाता हूं: मेरे पास बहुत कम सार्वजनिक विधियां हैं क्योंकि वास्तव में मेरी कक्षाओं का मुख्य मूल्य है (जैसा कि आपने कहा था कि मुझे ऐसा करना चाहिए)। हालाँकि, मैं 400 लाइन विधियों को लिखने से बचता हूँ, न तो सार्वजनिक और न ही निजी। इसलिए मेरी कुछ सार्वजनिक विधियाँ केवल दसियों निजी तरीकों की मदद से अपने लक्ष्य को प्राप्त कर सकती हैं। "बहुत जल्दी इसे ठीक करने के लिए" कोड। मैं डिबगर आदि .. शुरू कर दिया है
marstato

6
@marstato: सुझाव: पहले परीक्षण लिखना शुरू करें और अपने दिमाग को unittests के बारे में बदलें: उन्हें बग नहीं मिलते हैं, लेकिन सत्यापित करें कि कोड डेवलपर के रूप में काम करता है।
तीमुथियुस ट्रक

@marstato धन्यवाद! हाँ। परीक्षण हमेशा पहली बार पास करते हैं, जब आप सामान की जांच करते हैं (या आपने इसे चेक नहीं किया होगा!)। वे उपयोगी होते हैं, जैसा कि आप कोड को विकसित करते हैं, जब आप कुछ तोड़ते हैं तो आपको एक हेड-अप देते हैं, और यदि आपके पास अच्छे प्रतिगमन परीक्षण हैं, तो वे आपको समस्या के बारे में देखने के लिए COMFORT / GUIDANCE देते हैं (उस सामान में नहीं जो स्थिर है , और अच्छी तरह से प्रतिगमन परीक्षण किया गया)।
लुईस प्रिंगल

@marstato "इकाई परीक्षण का लक्ष्य यह इंगित करना है कि एक बग कहां है" - यह बिल्कुल गलतफहमी है जो ओपी के सवाल की ओर जाता है। इकाई परीक्षण का लक्ष्य एक एपीआई के इच्छित (और अधिमानतः प्रलेखित) व्यवहार को सत्यापित करना है।
स्टैक

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

3

UnitTests सार्वजनिक अवलोकन व्यवहार का परीक्षण करता है , न कि कोड, जहां "सार्वजनिक" का अर्थ है: निर्भरता के साथ मान और संचार लौटाएं।

एक "यूनिट" कोई भी कोड होता है, जो एक ही समस्या को हल करता है (या अधिक सटीक: बदलने का एक ही कारण है)। यह एक एकल विधि या कक्षाओं का एक समूह हो सकता है।

मुख्य कारण जो आप परीक्षण नहीं करना चाहते हैं वह private methodsहै: वे कार्यान्वयन विवरण हैं और आप उन्हें रीफ़ैक्टरिंग के दौरान बदलना चाह सकते हैं (कार्यक्षमता को बदले बिना ओओ-सिद्धांतों को लागू करके अपने कोड में सुधार करें)। यह ठीक उसी समय है जब आप अपने यूनिटीस्ट को बदलना नहीं चाहते हैं ताकि वे गारंटी दे सकें कि आपके CuT के व्यवहार को रिफैक्टरिंग के दौरान नहीं बदला।

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

मैं आमतौर पर इसके विपरीत अनुभव करता हूं: छोटी कक्षाएं (उनके पास कम जिम्मेदारी) उनके पास कम निर्भरता है, और आसान दोनों को लिखने और पढ़ने के लिए एकतरफा हैं।

आदर्श रूप से आप अपनी कक्षाओं में समान स्तर के अमूर्त पैटर्न लागू करते हैं। इसका मतलब यह है कि आपकी कक्षाएं या तो कुछ व्यावसायिक तर्क प्रदान करती हैं (अधिमानतः "शुद्ध कार्यों" के रूप में केवल अपने राज्य को बनाए रखने के बिना अपने मापदंडों पर काम करते हैं) (एक्स) या अन्य वस्तुओं पर कॉल के तरीके, दोनों एक ही समय में नहीं।

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


1

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

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

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

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

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

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


मैं इसके साथ संघर्ष करता हूं कि मैं निर्भरता का मजाक उड़ाता हूं कि अगर कोई निर्भरता इसे व्यवहार में बदलती है, तो मेरा परीक्षण विफल नहीं होगा। क्या यह विफलता एक एकीकरण परीक्षण में होने वाली है जो इकाई परीक्षण नहीं है?
टॉड

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

1

इस तरह के प्रश्न का उत्तर देने से पहले, आपको यह तय करने की आवश्यकता है कि आप वास्तव में क्या हासिल करना चाहते हैं।

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

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

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

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

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


0

हाँ, तुम पागल हो .... एक बॉक्स पसंद है!

निजी तरीकों का परीक्षण करने के कुछ तरीके हैं, जिनमें से कुछ भाषा पर निर्भर हैं।

  • प्रतिबिंब! नियम तोड़ने के लिए ही बनते हैं!
  • उन्हें संरक्षित, विरासत और ओवरराइड करें
  • दोस्त / प्रशिक्षु अदृश्य कक्षाएं

यदि आप निजी विधियों का परीक्षण करना चाहते हैं, तो इस पूरे मामले में, आप शायद उन्हें सार्वजनिक तरीकों पर निर्भरता और परीक्षण / इंजेक्शन के लिए स्थानांतरित करना चाहते हैं।


मुझे नहीं पता, मेरी नजर में आपने बताया कि यह अच्छा विचार नहीं है लेकिन इस सवाल का जवाब देना जारी रखा है
Liath

मुझे लगा कि मेरे पास सभी ठिकाने हैं :(
इवान

3
मैंने अपवित्र किया, क्योंकि सार्वजनिक एपीआई के लिए अपने निजी सहायक तरीकों को उजागर करने का विचार सिर्फ उन्हें पागल करने के लिए है, और मैंने हमेशा यही सोचा है।
रॉबर्ट हार्वे

0

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

मैं उन "निजी" तरीकों का परीक्षण करने के लिए एक अतिरिक्त internalएक्सेसर (फ्लैग InternalsVisibleToअसेंबली के साथ) स्पष्ट रूप से नामित किया गया हूं DoSomethingForTesting(parameters)

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

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