2009-08-19 7 views
6

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

मैं MVC में एक नियंत्रक है और एक कार्य एक पैकेज से इनकार करने के लिए एक सेवा कॉल:

public ActionResult Deny(int id) 
{ 
    service.DenyPackage(id); 

    return RedirectToAction("List"); 
} 

यह मेरे लिए स्पष्ट लगता है। एक नकली सेवा प्रदान करें, सत्यापित करें कि इसे सही ढंग से कहा गया था, किया गया।

public ActionResult Upload(int id) 
{ 
    var package = packageRepository.GetPackage(id); 
    var certificates = certificateRepository.GetAllCertificates(); 

    var view = new PackageUploadViewModel(package, certificates); 

    return View(view); 
} 

यह एक मैं थोड़ा पर स्टम्प्ड हूँ:

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

इसलिए राज्य आधारित परीक्षण के लिए मैं आईडी में पास करूंगा और फिर ActionResult के दृश्य का परीक्षण करूंगा। ठीक है, यह समझ में आता है। लेकिन क्या मेरे पास PackageUploadViewModel कन्स्ट्रक्टर पर कोई परीक्षण नहीं होगा? तो अगर मेरे पास कन्स्ट्रक्टर पर एक परीक्षण है, तो मेरा हिस्सा सिर्फ यह सत्यापित करना चाहता है कि मैं कन्स्ट्रक्टर को कॉल करता हूं और यह कि कंट्रोल रिटर्न कन्स्ट्रक्टर द्वारा लौटाता है।

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

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

मुझे कोई जानकारी नहीं है कि इससे कोई समझ हो।

वाह, यह लंबा है ...

उत्तर

5

मैं रॉय Osherove हाल ही में twitted एक सामान्य नियम के रूप में, अपने परीक्षण 95 प्रतिशत राज्य आधारित और 5 प्रतिशत बातचीत के आधार पर होना चाहिए कि लगता है। मैं सहमत हूँ।

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

ज्यादातर मामलों में, आप अपने एपीआई को डिज़ाइन कर सकते हैं ताकि राज्य-आधारित परीक्षण प्राकृतिक विकल्प हो, क्योंकि यह इतना आसान है।

अपने अपलोड उदाहरण की जांच करने के लिए: क्या इससे कोई फर्क पड़ता है कि GetPackage और GetAllCertificates को बुलाया गया था? क्या वास्तव में अपलोड विधि का अनुमानित परिणाम है?

मुझे नहीं लगता। मेरा अनुमान है कि अपलोड विधि का उद्देश्य - यह मौजूदा के लिए बहुत कारण है - सही दृश्य को पॉप्युलेट और सेवा देना है।

इसलिए राज्य-आधारित परीक्षण लौटाए गए व्यूअरसल्ट और इसके व्यू मॉडेल की जांच करेगा और सत्यापित करेगा कि इसमें सभी सही मान हैं।

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

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

यह परीक्षण ब्रेक होने से भी अधिक पसंद है, भले ही सभी लौटाए गए डेटा जैसा हो।

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

यह सब, और अधिक, उत्कृष्ट पुस्तक xUnit Test Patterns में बहुत अच्छी तरह से समझाया गया है।

+0

हाँ में "स्टब प्रश्नों, नकली कार्रवाई" की एक अनुमानी है, इंकार उदाहरण सुपर स्पष्ट है कि मैं बातचीत का परीक्षण किया जाना चाहिए था। अपलोड एक मुझे भ्रमित कर रहा था। मैं xUnit पैटर्न के साथ बाड़ पर था (यह स्पष्ट रूप से विशाल था और मुझे डर था कि मैं इसे खरीदूंगा और इसे नहीं पढ़ूंगा) लेकिन रेफ़रल इसके लायक हो सकता है। एक बात, और यह सिर्फ एक विवरण हो सकता है, लेकिन अपलोड एक का परीक्षण करने के लिए (जो मुझे एहसास करता है कि एक भयानक नाम क्या है कि कार्रवाई ... रिफैक्टर समय), मैं या तो (ए) मैन्युअल रूप से परीक्षण में दृश्य बना सकता हूं और सत्यापित करें कि दोनों विचार बराबर हैं या (बी) परीक्षण करें कि दृश्य पर प्रत्येक प्रॉपर्टी इसके बराबर है। पसंद? – anonymous

+0

@eyston: रॉय ओशरोव की पुस्तक "यूनिट परीक्षण की कला" एक अच्छा विकल्प है यदि आप डरते हैं कि दूसरा एक बहुत बड़ा मुंह वाला है - लेकिन आपको अभी भी इसे बाद की तारीख में पढ़ने की योजना बनाना चाहिए। –

+0

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

1

पूछने का सवाल यह है कि "यदि यह कोड काम करता है, तो मैं कैसे कह सकता हूं?" इसका मतलब कुछ इंटरैक्शन या कुछ राज्यों का परीक्षण करना हो सकता है, यह इस बात पर निर्भर करता है कि क्या महत्वपूर्ण है।

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

है यही कारण है कि हम http://www.mockobjects.com/book

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