क्या उन तरीकों को पेश करना ठीक है जो केवल यूनिट परीक्षणों के दौरान उपयोग किए जाते हैं?


12

हाल ही में मैं एक फैक्टरी विधि TDDing कर रहा था। विधि या तो एक सादे वस्तु, या एक डेकोरेटर में लिपटे ऑब्जेक्ट बनाने के लिए थी। सजाए गए ऑब्जेक्ट कई प्रकार के हो सकते हैं, जो सभी स्ट्रेटेजीक्लास का विस्तार कर रहे हैं।

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

मैं PHP में कोड करता हूं ताकि मैं ext/Reflectionलिपटे हुए ऑब्जेक्ट की एक कक्षा का पता लगाने के लिए उपयोग कर सकूं, लेकिन यह मुझे चीजों को ओवरकॉम्प्लिकेट करने वाला लग रहा था, और कुछ हद तक फिर से TDD के नियम।

इसके बजाय मैंने यह बताने का फैसला किया getClassName()कि स्ट्रैटेजीक्लास से कॉल करने पर ऑब्जेक्ट का क्लास नाम वापस आ जाएगा। हालांकि डेकोरेटर से कहा जाता है, यह सजाया वस्तु में उसी विधि द्वारा लौटाए गए मान को लौटाएगा।

इसे और अधिक स्पष्ट करने के लिए कुछ कोड:

interface StrategyInterface {
  public function getClassName();
}

abstract class StrategyClass implements StrategyInterface {
  public function getClassName() {
    return \get_class($this);
  }
}

abstract class StrategyDecorator implements StrategyInterface {

  private $decorated;

  public function __construct(StrategyClass $decorated) {
    $this->decorated = $decorated;
  }

  public function getClassName() {
    return $this->decorated->getClassName();
  }

}

और एक PHPUnit परीक्षण

 /**
   * @dataProvider providerForTestGetStrategy
   * @param array $arguments
   * @param string $expected
   */
  public function testGetStrategy($arguments, $expected) {

    $this->assertEquals(
      __NAMESPACE__.'\\'.$expected,  
      $this->object->getStrategy($arguments)->getClassName()
    )
  }

//below there's another test to check if proper decorator is being used

यहाँ मेरी बात यह है कि क्या ऐसे तरीकों को लागू करना ठीक है, जिनका यूनिट परीक्षणों को आसान बनाने के अलावा और कोई उपयोग नहीं है? किसी तरह यह मेरे लिए सही नहीं लगता है।


संभवतः यह प्रश्न आपके प्रश्न, programmers.stackexchange.com/questions/231237/… पर अधिक जानकारी फेंक देगा , मेरा मानना ​​है कि यह उपयोग पर निर्भर करता है और चाहे आप जो भी अनुप्रयोग विकसित कर रहे हैं, वह इकाई परीक्षण और डीबगिंग में बहुत मदद करेगा। ।
क्लेमेंट मार्क-आबा

जवाबों:


13

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

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


+1 ओपी 'स्पष्ट बॉक्स' इकाई परीक्षण का वर्णन कर रहा है, न कि TDD फीचर परीक्षण
स्टीवन ए। लोव

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

दूसरी ओर और इस सवाल के आलोक में: programmers.stackexchange.com/questions/86656/... जब हम "इकाई परीक्षण" इस बिल्कुल ठीक (अभी भी डेटाबेस पाइपलाइन हालांकि: पी) हो जाता है से "TDD परीक्षण" भेद
Mchl

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

5

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

इसे संभालने का मेरा पसंदीदा तरीका है (और मुझे माफी मांगनी होगी कि मैं यह नहीं दिखा सकता कि पीएचपी में यह कैसे किया जा सकता है क्योंकि मैं मुख्य रूप से सी-स्टाइल भाषाओं में कोड हूं) 'टेस्ट' फ़ंक्शन को इस तरह से प्रदान करना है कि वे नहीं हैं वस्तु द्वारा बाहरी दुनिया के सामने, लेकिन व्युत्पन्न वस्तुओं द्वारा पहुँचा जा सकता है। परीक्षण के उद्देश्यों के लिए मैं तब एक वर्ग प्राप्त करूंगा जो उस वस्तु के साथ सहभागिता को नियंत्रित करेगा जिसे मैं वास्तव में परीक्षण करना चाहता हूं और उस विशेष वस्तु का उपयोग इकाई परीक्षण में करना है। एक C ++ उदाहरण कुछ इस तरह दिखाई देगा:

उत्पादन प्रकार वर्ग:

class ProdObj
{
  ...
  protected:
     virtual bool checkCertainState();
};

टेस्ट सहायक श्रेणी:

class TestHelperProdObj : public ProdObj
{
  ...
  public:
     virtual bool checkCertainState() { return ProdObj::checkCertainState(); }
};

इस तरह, आप कम से कम एक ऐसी स्थिति में हैं जहाँ आपको अपने मुख्य ऑब्जेक्ट में 'परीक्षण' प्रकार के कार्यों को उजागर करने की आवश्यकता नहीं है।


एक दिलचस्प दृष्टिकोण। मुझे यह देखने की ज़रूरत है कि मैं इसे कैसे अनुकूलित कर सकता हूं
20

3

कुछ महीने पहले जब मैंने अपने नए खरीदे हुए डिशवॉशर को रखा तो उसमें से बहुत सारा पानी निकल गया। असेंबली लाइन में परीक्षण के उद्देश्य से बढ़ते-बढ़ते छेद और सामान को मशीनरी पर देखना असामान्य नहीं है।

परीक्षण महत्वपूर्ण है, अगर जरूरत है, तो बस इसके लिए कुछ जोड़ें।

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

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


1

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

जब यह ठीक हो:

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

जब यह ठीक नहीं है:

  • यदि विधि कुछ ऐसा लगता है जो कभी उपयोगी नहीं होगा, या अन्य इंटरफ़ेस विधियों के संबंध में कोई मतलब नहीं है, तो यह गुप्त या भ्रमित हो सकता है। उस समय, यह उस वस्तु के बारे में मेरी समझ को खराब कर देगा।
  • जेरेमी का उदाहरण, "... जब आपको यह जानने की आवश्यकता होती है कि कुछ दिनचर्या कितनी कुशल होती है, उदाहरण के लिए आपका हैशमैप हेश मूल्यों के समान रूप से वितरित रेंज का उपयोग करता है - बाहरी इंटरफ़ेस में कुछ भी आपको यह बताने में सक्षम नहीं होगा।"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.