2012-08-17 8 views
7

मैं Clean Code: A Handbook of Agile Software Craftsmanship पढ़ रहा हूं और उदाहरणों में से एक में Portfolio वर्ग और TokyoStockExchange कक्षा शामिल है। हालांकि, Portfolio बहुत टेस्टेबल नहीं है क्योंकि यह पोर्टफोलियो के मूल्य को निर्धारित करने के लिए बाहरी API के रूप में TokyoStockExchange पर निर्भर करता है और यह काफी अस्थिर लुकअप है और परीक्षण करने के लिए अनुकूल नहीं है।इस बारे में भ्रमित है कि यह इकाई परीक्षण डमी ऑब्जेक्ट्स के लिए उपयोगी क्यों है

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

public class PortfolioTest 
{ 
    private DummyStockExchange exchange; 
    private Portfolio portfolio; 

    protected void setUp() 
    { 
     exchange = new DummyStockExchange(); 
     exchange.fix("MSFT", 100); 
     portfolio = new Portfolio(exchange); 
    } 

    public void GivenFiveMSFTTotalShouldBe500() 
    { 
     portfolio.add(5, "MSFT"); 
     Assert.assertEquals(500, portfolio.value()); 
    } 
} 

मेरा प्रश्न हैं, बस, क्यों है: यहाँ कोड है?

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

यह सब सिर्फ यह नहीं पता कि हमारे योजक प्रोग्राम काम करते हैं या नहीं, लेकिन उपलब्ध संख्या केवल यादृच्छिक रूप से जेनरेट की जाती है, इसलिए हम एक डमी क्लास बनाते हैं जो हमें 2 देता है और 2 + 2 = 4 पर परीक्षण करता है। खैर हाँ, जाहिर है कि यह सच है। हम अभी भी TokyoStockExchange तोड़ सकते हैं और परीक्षण अभी भी सफल होगा क्योंकि यह किसी अन्य वर्ग का परीक्षण कर रहा है। यदि कुछ भी यह भ्रामक लगता है और इसके परिणामस्वरूप हमें कुछ पता लगाने के लिए अतिरिक्त कोड लिखना पड़ता है जो हम जानते हैं कि काम करने जा रहा है।

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

+0

संदर्भ के लिए ... यदि आप परीक्षण कर रहे हैं कि '' पोर्टफोलियो 'के साथ 'टोक्योस्टॉक एक्सचेंज' काम * है, तो आप इकाई परीक्षण के दायरे से बाहर हैं। 'पोर्टफोलियो 'और' टोक्योस्टॉक एक्सचेंज 'इकाइयां हैं, और यूनिट परीक्षण का उद्देश्य प्रत्येक * यूनिट * को जितना संभव हो उतना अलग से (अन्य सभी) से अलग करने का इरादा है। उनके बीच बातचीत * एकीकरण परीक्षण * कवर है। – cHao

+2

+1 "परीक्षण को बनाए रखने के लिए यह अधिक काम है" के साथ इकाई परीक्षण को उड़ाने के बजाय मूल्य को समझने की कोशिश करने के लिए +1 –

+0

यह वास्तव में [programmers.se] के लिए एक प्रश्न है। –

उत्तर

7

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

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

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

+3

+1 बिल्कुल। आप टोक्योस्टॉक एक्सचेंज का परीक्षण नहीं कर रहे हैं, आप परीक्षण कर रहे हैं कि पोर्टफोलियो क्लास सही तरीके से काम करता है। – CaffGeek

+0

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

+0

इसके अलावा, एक पूर्ण ज्ञात ** निर्भरता ** बनाकर, आप परीक्षण के प्रश्न से ** विविधता ** हटा देते हैं। यह एक आधारभूत रेखा बनाता है जिससे आप कह सकते हैं "यह ऑब्जेक्ट मानक या अपेक्षित इनपुट दिए जाने पर बिल्कुल अपेक्षित काम करता है।" इस पर विचार करें कि निर्भरता डेटाबेस कनेक्शन बनाता है लेकिन यह कनेक्शन किसी कारण से विफल रहता है ... आप नहीं चाहते कि यह परीक्षण विफल हो जाए क्योंकि यह आपके द्वारा परीक्षण किए जा रहे कार्यों का प्रतिनिधि नहीं है। –

3

दो प्रकार के परीक्षण हैं जो आपको करना चाहिए, यूनिट परीक्षण और एकीकरण परीक्षण।

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

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

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

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

संबंधित मुद्दे

 संबंधित मुद्दे