अगर मुझे पहले से ही एकीकरण परीक्षण है, तो क्या मुझे यूनिट टेस्ट की आवश्यकता है?


47

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

मुझे पता है कि एकीकरण परीक्षण पर इकाई परीक्षण के लाभ क्या हैं

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

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


जिज्ञासा से बाहर, आपके एकीकरण परीक्षणों में कितना कवरेज है? इसके अलावा, यदि आपके पास कुछ जटिल तर्क हैं, तो क्या आपके एकीकरण परीक्षण उन सभी या इसके एक हिस्से को कवर करते हैं और कौन से हिस्से, व्यवसाय या यादृच्छिक के लिए महत्वपूर्ण हैं?
सिवन

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

जवाबों:


33

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

  • लघु और तेज इकाई परीक्षण का एक अच्छा पहलू है, हालांकि किसी भी तरह से सबसे महत्वपूर्ण नहीं है।
  • पता लगाना-बग [एस] -इस अत्यंत मूल्यवान है। पेशेवर सॉफ्टवेयर विकास के कई अध्ययनों से पता चला है कि बग की लागत में तेजी से वृद्धि होती है क्योंकि यह उम्र और सॉफ़्टवेयर-वितरण पाइपलाइन को स्थानांतरित करता है।
  • ढूँढना-नकाबपोश-कीड़े मूल्यवान हैं। जब आप जानते हैं कि किसी विशेष घटक के अपने सभी व्यवहार सत्यापित हैं, तो आप इसे उन तरीकों से उपयोग कर सकते हैं जो पहले उपयोग नहीं किए गए थे, आत्मविश्वास के साथ। यदि एकमात्र सत्यापन एकीकरण परीक्षण के माध्यम से होता है, तो आप केवल यह जानते हैं कि इसका वर्तमान उपयोग सही तरीके से व्यवहार करता है।
  • वास्तविक दुनिया के मामलों में मज़ाक करना महंगा है, और नकली बनाए रखना दोगुना है। वास्तव में, जब "दिलचस्प" ऑब्जेक्ट्स या इंटरफेस का मजाक उड़ाते हैं, तो आपको उन परीक्षणों की भी आवश्यकता हो सकती है जो यह सत्यापित करते हैं कि आपके नकली ऑब्जेक्ट आपकी वास्तविक वस्तुओं को सही ढंग से मॉडल करते हैं!

मेरी पुस्तक में, पेशेवरों ने विपक्ष को पछाड़ दिया।


2
क्या वास्तविक दुनिया के मामलों में सस्ता नहीं है ? आप केवल इस बात की अपेक्षाएं कर रहे हैं कि मॉक को क्या संदेश मिले और यह निर्दिष्ट करें कि वह क्या लौटाएगा।
डॉगवेदर

10
जब पहली बार बनाया गया तो @ डॉगवेर मोक्स अच्छी तरह से काम करते हैं। जैसे-जैसे समय बीतता है और वास्तविक वस्तु बदल जाती है, मोक्स को उसके साथ बदलना पड़ता है। सड़क के नीचे 10 साल और 6,000 यूनिट परीक्षण, यह जानना बहुत मुश्किल है कि आपके "सफल" परीक्षण वास्तव में सफल हैं।
रॉस पैटरसन

1
एक तरफ के रूप में, कि "10 साल और 6,000 यूनिट परीक्षण" व्यक्तिगत अनुभव से संख्याएं हैं, हाइपरबोले नहीं।
रॉस पैटरसन

3
मैंने 2004 या 2005 में स्वचालित डेवलपर परीक्षण (इकाई और एकीकरण, लेकिन ज्यादातर बाद वाले) वापस लिखना शुरू कर दिया और जावा के लिए एक उन्नत मॉकिंग लाइब्रेरी विकसित की। कई बार मैंने इसी कारण (DB, या एक नेटवर्क परिवर्तन में एक परिवर्तन की तरह) के लिए तोड़ने के कई एकीकरण परीक्षणों को देखा, और मैं कभी कभी "निचले स्तर" पुन: प्रयोज्य घटकों के लिए एकीकरण परीक्षणों लिखते हैं, लेकिन अभी भी, मैं बहुत पसंद करते हैं केवल है एकीकरण परीक्षण। मॉकिंग के साथ पृथक इकाई परीक्षण, ज्यादातर समय, इसके लायक नहीं हैं; मैं केवल एकीकरण परीक्षणों के लिए सहायता के रूप में मॉकिंग लागू करता हूं।
रोजेरियो

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

8

मैं एक मौजूदा एकीकरण-टेस्टकेस को यूनीटेस्ट के रूप में लागू करने में बहुत अधिक मूल्य नहीं देखता हूं।

गैर-टीडी विरासत अनुप्रयोगों के लिए एकीकरण परीक्षण अक्सर लिखना बहुत आसान होता है क्योंकि आमतौर पर कार्यात्मकता-से-परीक्षण किया जाता है, इसलिए कसकर युग्मित किया जाता है ताकि अलगाव (= unittesting) में परीक्षण इकाइयां विभेदित / महंगी / असंभव हो सकें।

> Then what are the reasons to write/add unit tests?

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

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

यदि आप TDD करते हैं तो कोड स्वचालित रूप से आसान परीक्षण योग्य है।


2
यदि मेरे पास कोई विरासत आवेदन नहीं है unit-tests, और मैं unit-testsकुछ हिस्सों को शामिल करना चाहता हूं , तो क्या आपको लगता है integration testsकि विरासत कोड के लिए पहले लिखना बेहतर होगा । एक बार जो लिखा गया है, तो आप तंग युग्मन को खोल सकते हैं, और उन इंटरफेस के साथ फ़ंक्शन बना सकते हैं जिन्हें परीक्षण किया जा सकता है? चूँकि आपके पास integration-testपहले से ही लिखा हुआ है, आप फिर से रिफैक्टरिंग के प्रत्येक चरण में सत्यापित कर सकते हैं कि कोड का नया संस्करण अभी भी वांछित है?
अल्फा_989

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

5

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


4

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

इसके अलावा, एक बड़ी गलती जो आप कर रहे हैं, वह है कि भरोसा करना

Find bug that may not be caught in integration test. e.g. masking/offsetting bugs.

महत्वपूर्ण नहीं है। क्या आप उम्मीद कर रहे हैं कि आपके उपयोगकर्ता आपके लिए बग ढूंढ सकते हैं? एकीकृत परीक्षणों से प्राप्त कवरेज पर भरोसा करना मेरी राय में खतरनाक है, आप बहुत आसानी से कवरेज का उच्च% प्राप्त कर सकते हैं लेकिन वास्तव में आप बहुत कम परीक्षण कर रहे हैं।

मुझे लगता है कि एकीकृत परीक्षण के खिलाफ विहित संदर्भ जेब्रिन के पद हैं:

http://www.jbrains.ca/permalink/integrated-tests-are-a-scam-part-1

यदि आपने उन्हें पहले ही नहीं पढ़ा है तो

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


मुझे वास्तव में वह लेख नहीं मिला। तो बहुत सारे कोड पथ और एकीकरण परीक्षण उन सभी को कवर नहीं कर सकते हैं ... तो? एक ही बात इकाई परीक्षणों पर लागू होती है जब तक कि आपकी इकाइयाँ इतनी तुच्छ न हों जितना कि व्यर्थ होना।
केसी

यह एक से अधिक कोड कवरेज पर फिक्सिंग के खिलाफ एक तर्क की तरह अधिक है कि आपको एक टन यूनिट टेस्ट लिखना चाहिए और एकीकरण परीक्षण करना चाहिए।
केसी

1

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

हां, पहले अपने एकीकरण और इकाई परीक्षणों को लिखना बेहतर है, लेकिन बाद में लिखे जाने पर भी उनके पास होने का बहुत मूल्य है।


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