क्या आप परीक्षण के लिए निजी सामान को आंतरिक / सार्वजनिक करेंगे, या किसी तरह के हैक का उपयोग करेंगे जैसे कि PrivateObject?


26

मैं कोड परीक्षण में काफी शुरुआती हूं, और assertपहले एक वेश्या थी। यूनिट टेस्टिंग में एक बात मुझे चिंता में डालती है, वह यह है कि अक्सर आपको public(या कम से कम internal) फ़ील्ड बनाने की आवश्यकता होती है, जो privateअन्यथा, अन- readonlyउन्हें, इसके बजाय privateतरीके बनाने protected virtual, आदि ...

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

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


2
अजगर लोग केवल सार्वजनिक होते हैं। वे खुश हैं। चिंता क्यों? सब कुछ सार्वजनिक क्यों नहीं करते?
S.Lott

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

2
@ रिग: पायथन एक शीर्ष भाषा नहीं है? दिलचस्प।
S.Lott

7
"यह शीर्ष भाषाओं के बहुमत में सर्वोत्तम प्रथाओं से बहुत दूर है" तार्किक रूप से इसका मतलब नहीं है (या यहां तक ​​कि उस पर भी) "पायथन एक शीर्ष भाषा नहीं है"।
माइक नाकिस

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

जवाबों:


36

आपको कभी-कभी नहीं करना चाहिए

मेक public(या कम से कम internal) फ़ील्ड जो privateअन्यथा होते, readonlyउन्हें संयुक्त राष्ट्र बनाने के लिए, इसके बजाय privateतरीके बनातेprotected virtual

विशेष रूप से संयुक्त राष्ट्र के एक क्षेत्र को पढ़ना एक अपरिवर्तनीय वस्तु को परिवर्तनशील बना सकता है, और यह एक आपदा होगी।

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

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

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


2
ठीक ठीक! यदि आप इसे प्रतिबिंब या हैक्स के बिना इकाई का परीक्षण नहीं कर सकते हैं, तो शायद आपको अपने एपीआई या अपने डिजाइन में गलती मिल गई है।
फाल्कन

क्या आप यह कह रहे हैं कि परीक्षणों में मज़ाक करने में मदद करने के privateतरीके बनाना protected virtualबुरा व्यवहार माना जाता है?
रोबुला

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

13

C # में आप InternalsVisibleToAttributeअपने टेस्ट असेंबली को internalउन विधानसभा में कक्षाओं को देखने की अनुमति देने के लिए उपयोग कर सकते हैं जिनका आप परीक्षण कर रहे हैं। ऐसा लगता है कि आप पहले से ही यह जानते हैं।

ज्यादातर मामलों में मैं केवल अपने विधानसभा के सार्वजनिक एपीआई के परीक्षण में दिलचस्पी लेता हूं। ऐसे मामले में जहां मैं किसी इकाई का व्हाइट-बॉक्स परीक्षण करना चाहता हूं, मैं कोड को एक internalकक्षा में ले जाता हूं , और इसे publicउस कक्षा का एक तरीका बनाता हूं । फिर मैं उस क्लास के लिए एक यूनिट टेस्ट कोड कर सकता हूं।

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


8

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

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

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

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

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


6

व्यक्तिगत रूप से मैं उस कोड को छोड़ना पसंद करता हूं जिसका मैं परीक्षण कर रहा हूं जैसा कि मैं कर सकता हूं और यदि परीक्षण कोड को हैक की आवश्यकता है (और सी ++ में गंदा पॉइंटर्स आदि) तो मुझे ऐसा करने में खुशी है।



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

@AlanDelimon क्या यह बाद के रखरखाव प्रोग्रामरों के दिमाग को चोट नहीं पहुंचा सकता है?
राजहंस का स्वर्गवास

1
@flamingpenguin बदसूरत कोड प्रोग्रामर को कहीं भी चोट पहुंचा सकते हैं; लेकिन बदसूरत परीक्षण कोड संभवतः कम नुकसान पहुंचाएगा क्योंकि यह केवल वर्ग को संशोधित करने वाले लोगों को प्रभावित करेगा और उन लोगों को भी नहीं जो केवल इसका उपभोग करते हैं।
दान नीली

2
@flamingpenguin यह हो सकता है, लेकिन अगर आपको कहीं पर बदसूरत कोड डालना है, तो यह एक इकाई परीक्षण में भी हो सकता है, जहां संशोधन की आवश्यकता कम है और आवेदन का हिस्सा हो सकता है।
एलन डेलिमोन

5

आपके कोड की दृश्यता का आपके यूनिट परीक्षणों से कोई लेना-देना नहीं है!

आप अपने तरीकों को निजी बनाने के उद्देश्य से उन्हें परीक्षण से छिपाते हैं और आप उन्हें परीक्षण के लिए सार्वजनिक करने के लिए नहीं बनाते हैं, है ना? यह आपका इम्प्लांटेशन है जो यहां जरूरी है, न कि परीक्षणों में - जो सर्वर आपके कोड के प्रमाण के रूप में हैं, लेकिन वे आपके कोड नहीं हैं

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

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