क्या यूनिट परीक्षणों को मेरे अपने तरीकों का उपयोग नहीं करना चाहिए?


83

आज मैं एक " JUnit मूल बातें" वीडियो देख रहा था और लेखक ने कहा कि जब आपके कार्यक्रम में किसी दिए गए तरीके का परीक्षण किया जाता है, तो आपको प्रक्रिया में अपने स्वयं के अन्य तरीकों का उपयोग नहीं करना चाहिए।

अधिक विशिष्ट होने के लिए, वह कुछ रिकॉर्ड-निर्माण विधि का परीक्षण करने के बारे में बात कर रहा था जो तर्कों के लिए एक नाम और अंतिम नाम लेती थी, और इसने उनका उपयोग किसी दिए गए तालिका में रिकॉर्ड बनाने के लिए किया। लेकिन उन्होंने दावा किया कि इस पद्धति के परीक्षण की प्रक्रिया में, उन्होंने अंतिम परिणाम की जांच करने के लिए डेटाबेस को क्वेरी करने के लिए अपने अन्य DAO विधियों का उपयोग नहीं किया (यह जांचने के लिए कि रिकॉर्ड वास्तव में सही डेटा के साथ बनाया गया था)। उन्होंने दावा किया कि इसके लिए, उन्हें डेटाबेस की क्वेरी करने और परिणाम की जांच करने के लिए अतिरिक्त JDBC कोड लिखना चाहिए ।

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

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

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

क्या आप कृपया इस बारे में अपनी जानकारी साझा कर सकते हैं?


79
एक इकाई परीक्षण को देखना थोड़ा अजीब है जिसमें सभी डेटाबेस शामिल हैं
रिचर्ड टिंगल

4
IMO अन्य वर्गों IFF को कॉल करना ठीक है, वे काफी तेज हैं। ऐसी किसी भी चीज़ का मज़ाक करना जिसे डिस्क पर या किसी नेटवर्क पर जाना हो। सादे ओल 'क्लास IMO का मजाक उड़ाने में कोई समझदारी नहीं है।
रबड़डक सिप

2
इस वीडियो का लिंक है?
कैंडिड_ऑरेंज सेप

17
" VBA के लिए रूबरडैक के लिए ठीक से यूनिट-टेस्टेड धन्यवाद " - आपने सर, अभी-अभी मेरा दिन बनाया है। मैं टाइपो को ठीक करूँगा और इसे "रबरडक" से "रबरडक" में संपादित करूँगा, लेकिन मुझे ऐसा महसूस होगा कि कुछ स्पैमर ऐसा कर रहा है और रबरडुकब.कॉम के लिए एक लिंक जोड़ रहा है (मेरे पास डोमेन नाम और सह-प्रोजेक्ट के साथ स्वयं का प्रोजेक्ट है) @ रबरडक) - तो मैं यहाँ केवल इसके बजाय टिप्पणी करूँगा। वैसे भी यह वास्तव में पिछले दो वर्षों के बेहतर हिस्से के लिए मेरी नींद हराम रातों के लिए जिम्मेदार उपकरण का उपयोग करने वाले लोगों को देखने के लिए बहुत बढ़िया है! =)
मैथ्यू गुइंडन

4
@ MatMug और RubberDuck मुझे पसंद है कि आप रबरडक के साथ क्या कर रहे हैं। कृपया इसे बनाए रखें। निश्चित रूप से इसकी वजह से मेरा जीवन आसान है (मैं एक्सेल VBA में बहुत सारे छोटे कार्यक्रम और प्रोटोटाइप बनाने के लिए होता हूं)। बीटीडब्लू, मेरी पोस्ट में रबरडक का उल्लेख सिर्फ मुझे था कि मैं खुद रबरडैक के लिए अच्छा बनने की कोशिश कर रहा था, जो पीई में यहां मेरे लिए अच्छा था । :)
कार्लोसियरा

जवाबों:


186

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

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

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


117
व्यावहारिकता के लिए हुर्रे।
रॉबर्ट हार्वे

6
मैं यह जोड़ना चाहूंगा कि यह विश्वसनीयता बहुत अधिक नहीं है क्योंकि यह गति है जो कि समस्या है जो निर्भरता को कम करने की ओर ले जाती है। अलगाव मंत्र में परीक्षण इतना सम्मोहक है कि यह तर्क अक्सर छूट जाता है।
माइकल डुरेंट

4
"... इकाई परीक्षण एक उपकरण है, और यह आपके उद्देश्यों की सेवा करने के लिए है, यह प्रार्थना करने के लिए एक वेदी नहीं है।" - यह
वेन कॉनराड

15
"नहीं एक वेदी से प्रार्थना की जा करने के लिए" - नाराज TDD आने वाले कोच!
डेन

5
@ jpmc26: इससे भी बदतर आप अपने सभी यूनिट परीक्षणों को पारित नहीं करना चाहते हैं क्योंकि वे वेब सेवा को सही तरीके से संभाल रहे हैं, जो कि एक मान्य और सही व्यवहार है, लेकिन वास्तव में जब यह ऊपर होता है तब कभी भी कोड का प्रयोग नहीं करता है! एक बार जब आप इसे चुरा लेते हैं, तो आपको यह चुनना है कि यह "ऊपर" या "नीचे" है और दोनों का परीक्षण करें।
स्टीव जेसप

36

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

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

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

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

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

चाहे आपको एकीकरण परीक्षण या इकाई परीक्षण पर निर्भर होना चाहिए या दोनों चर्चा का एक बड़ा विषय है।


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

11
"दूसरों के लिए," यूनिट टेस्ट "शब्द बहुत अधिक ढीला है" - कुछ और से अलग, तथाकथित "यूनिट टेस्टिंग फ्रेमवर्क" उच्च-स्तरीय परीक्षणों को व्यवस्थित और चलाने के लिए वास्तव में सुविधाजनक तरीका है ;-)
स्टीव जेसप

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

1
अपनी पहली श्रेणी में उन की बहुत बड़ी संख्या है, बेशक @EricKing, बहुत विचार डेटाबेस को शामिल करने की बिल्कुल भी इकाई परीक्षण में अभिशाप है, चाहे आप अपने DAOs का उपयोग करें या डेटाबेस सीधे टक्कर मार दी।
पेरिअटा ब्रीटाटा

1
@AmaniKilumanga सवाल मूल रूप से "किसी ने कहा था कि मुझे यूनिट परीक्षणों में यह बात नहीं करनी चाहिए, लेकिन मैं इसे यूनिट परीक्षणों में करता हूं और मुझे लगता है कि यह ठीक है। क्या यह ठीक है?" और मेरा जवाब था "हाँ, लेकिन ज्यादातर लोग एक इकाई परीक्षण के बजाय एक एकीकरण परीक्षण कहेंगे।" जहाँ तक आपके सवाल का, मुझे नहीं पता कि आपके द्वारा "एकीकरण कोड उत्पादन कोड विधियों का उपयोग कर सकते हैं?"
एरिक किंग

7

जवाब हां और नहीं है...

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

ये क्रॉस-यूनिट परीक्षण कोड कवरेज के लिए अच्छे होते हैं और जब कार्यक्षमता को समाप्त करने के लिए परीक्षण समाप्त होता है, लेकिन वे कुछ कमियां लेकर आते हैं जिनके बारे में आपको पता होना चाहिए:

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

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

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


4

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

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


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

1

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

डेटाबेस में रिकॉर्ड बनाया गया है या नहीं, यह परीक्षण करना बाकी सिस्टम के संपर्क में आने वाली कार्यक्षमता की इकाई का परीक्षण करने के बजाय भंडारण तंत्र के कार्यान्वयन विवरण से संबंधित है।

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

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


1

भावना सही है।

आदर्श रूप से, एक इकाई परीक्षण में , आप एक इकाई (एक व्यक्तिगत विधि या छोटी कक्षा) का परीक्षण कर रहे हैं ।

आदर्श रूप में, आप पूरे डेटाबेस सिस्टम को स्टब करेंगे। यानी, आप अपने तरीके को फेक वातावरण में चलाएंगे और यह सुनिश्चित करेंगे कि यह सही क्रम में सही DB APIs को कॉल करे। आप स्पष्ट रूप से, सकारात्मक रूप से अपने स्वयं के तरीकों में से एक का परीक्षण करते समय डीबी का परीक्षण नहीं करना चाहते हैं।

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

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

ध्यान दें कि अन्य परीक्षण भी हैं, जैसे फीचर परीक्षण, व्यवहार परीक्षण आदि जो इस दृष्टिकोण से अलग हैं - "यूनिट परीक्षण" के साथ "परीक्षण" को भ्रमित न करें।


"बस यह सुनिश्चित करें कि यह सही क्रम में सही DB APIs कहता है" - हाँ, निश्चित। जब तक यह पता नहीं चल जाता है कि आपने दस्तावेज़ को गलत कर दिया है और आपके द्वारा उपयोग किया जा रहा वास्तविक सही क्रम पूरी तरह से अलग है। अपने नियंत्रण के बाहर सिस्टम का मजाक न करें।
जोकर_vD

4
@ जोकर_vD यही एकीकरण परीक्षण है। यूनिट परीक्षणों में, बाहरी प्रणालियों का बिल्कुल मजाक उड़ाया जाना चाहिए।
बेन आरोनसन

1

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

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

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


1

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

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

@Test
public void canSaveData() {
    writeDataToDatabase();
    // what can you assert - the only expectation you can have here is that an exception was not thrown.
}

@Test
public void canReadData() {
    // how do I even get data in there to read if I cannot call the method which writes it?
}

परीक्षण विधियों के परिप्रेक्ष्य के कारण यह समस्या होती है। तरीकों का परीक्षण न करें। परीक्षण व्यवहार। WidgetDao वर्ग का व्यवहार क्या है? यह विजेट्स को बनाए रखता है। ठीक है, आप कैसे सत्यापित करते हैं कि यह विगेट्स बना रहता है? खैर, दृढ़ता की परिभाषा क्या है? इसका मतलब है जब आप इसे लिखते हैं, तो आप इसे फिर से पढ़ सकते हैं। तो पढ़ो + लिखो एक साथ एक परीक्षा बन जाती है, और मेरी राय में, एक अधिक सार्थक परीक्षा।

@Test
public void widgetsCanBeStored() {
    Widget widget = new Widget();
    widget.setXXX.....
    // blah

    widgetDao.storeWidget(widget);
    Widget stored = widgetDao.getWidget(widget.getWidgetId());
    assertEquals(widget, stored);
}

यह एक तार्किक, सामंजस्यपूर्ण, विश्वसनीय और मेरी राय में, सार्थक परीक्षण है।

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

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


बहुत ही व्यावहारिक दृष्टिकोण, और जैसा कि आप कहते हैं, मुझे लगता है कि आपको वास्तव में मेरे पास एक मुख्य संदेह था। धन्यवाद!
carlossierra

0

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

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

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

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

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

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

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

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

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

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


0

यह मुझे ऐसा करना पसंद है। यह सिर्फ एक व्यक्तिगत पसंद है क्योंकि यह उत्पाद के परिणाम को प्रभावित नहीं करेगा, केवल इसे उत्पादित करने का तरीका।

यह आपके द्वारा परीक्षण किए जा रहे एप्लिकेशन के बिना आपके डेटाबेस में नकली मान जोड़ने में सक्षम होने के लिए possibilites पर निर्भर करता है।

मान लीजिए कि आपके दो परीक्षण हैं: A - डेटाबेस B को पढ़ना - डेटाबेस में सम्मिलित करना (A पर निर्भर करता है)

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

मैं इकाई-परीक्षण में कुछ प्रश्न लिखने की कोशिश नहीं करूंगा क्योंकि आपको आवेदन के पीछे DB संरचना को जानने में सक्षम नहीं होना चाहिए (या यह बदल सकता है)। मतलब आपका टेस्ट केस आपके कोड की वजह से ही फेल हो सकता है। जब तक आप टेस्ट के लिए टेस्ट नहीं लिखेंगे, लेकिन टेस्ट के लिए कौन टेस्ट देगा ...


-1

अंत में, यह नीचे आता है कि आप क्या परीक्षण करना चाहते हैं।

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

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

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

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


@downvoters: क्या आप मुझे अपने कारण बता सकते हैं ताकि मैं उन पहलुओं पर सुधार कर सकूं जो आपको लगता है कि मेरे उत्तर में कमी है?
हॉफमैले
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.