2008-08-22 15 views
32

पिछली गर्मियों में मैं एक मूल ASP.NET/SQL सर्वर CRUD ऐप विकसित कर रहा था, और इकाई परीक्षण आवश्यकताओं में से एक था। जब मैंने डेटाबेस के खिलाफ परीक्षण करने की कोशिश की तो मैं कुछ परेशानी में भाग गया। मेरी समझ के लिए, इकाई परीक्षण किया जाना चाहिए:यूनिट-परीक्षण डेटाबेस

  • राज्यविहीन
  • एक दूसरे को
  • repeatable से स्वतंत्र एक ही परिणाम यानी कोई निरंतर आ रही है बदलता है

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

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

मुझे मिला एक और समाधान एक लेनदेन में फ़ंक्शन कॉल को लपेटना है जिसे आसानी से वापस ले जाया जा सकता है, जैसे Roy Osherove's XtUnit। यह काम, लेकिन इसमें एक और लाइब्रेरी, एक और निर्भरता शामिल है, और यह समस्या के समाधान के लिए बहुत अधिक भारी लगता है।

तो, इस स्थिति के साथ सामना करते समय एसओ समुदाय ने क्या किया है?


tgmdbm ने कहा:

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

तो अगर मैं इस सही ढंग से पढ़ा है, वहाँ वास्तव में प्रभावी रूप से इकाई परीक्षण एक डेटा एक्सेस परत करने के लिए कोई रास्ता नहीं है। या, डेटा एक्सेस लेयर का "यूनिट टेस्ट" डेटाबेस के साथ वास्तविक इंटरैक्शन से स्वतंत्र, वर्गों द्वारा जेनरेट किए गए SQL/कमांड परीक्षण, कहता है?

उत्तर

25

तालिकाओं के अस्तित्व के अलावा किसी अन्य डेटाबेस का परीक्षण करने का कोई वास्तविक तरीका नहीं है, अपेक्षित कॉलम हैं, और उचित बाधाएं हैं। लेकिन आमतौर पर यह वास्तव में करने लायक नहीं है।

आप आमतौर पर इकाई डेटाबेस का परीक्षण नहीं करते हैं। आप आमतौर पर एकीकरण परीक्षण में डेटाबेस शामिल करते हैं।

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

11

DBunit

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

5

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

Rhino Mocks वह एक है जो बहुत अच्छी प्रतिष्ठा रखता है।

NMock दूसरा है।

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

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

जहां मैं काम करता हूं, हम आम तौर पर खरोंच से अपना खुद का नकली libs बनाते हैं, लेकिन इसका मतलब यह नहीं है कि आपको करना है।

1

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

4

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

मैं आपके मॉकिंग फ्रेमवर्क के रूप में Moq अत्यधिक अनुशंसा करता हूं। मैंने राइनो मोक्स और एनएमॉक का उपयोग किया है। Moq इतना आसान था और अन्य ढांचे के साथ मेरी सभी समस्याओं का समाधान किया।

0

यदि आप LINQ से SQL का उपयोग ओआरएम के रूप में कर रहे हैं तो आप डेटाबेस पर ऑन-द-फ्लाई उत्पन्न कर सकते हैं (बशर्ते कि आपके पास इकाई परीक्षण के लिए उपयोग किए गए खाते से पर्याप्त पहुंच हो)। देखें http://www.aaron-powell.com/blog.aspx?id=1125

2

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

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

Unit Test Patterns

2

मैं एक तकनीक है कि मैं इस बहुत स्थिति here के लिए उपयोग किया गया है के बारे में बताया ।

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

एकमात्र मुद्दा जो आपको "महान" नहीं मिल सकता है वह यह है कि मैं आम तौर पर एक संपूर्ण सीआरयूडी परीक्षण (यूनिट परीक्षण परिप्रेक्ष्य से शुद्ध नहीं) करता हूं लेकिन यह एकीकरण परीक्षण आपको कार्रवाई में अपना सीआरयूडी + मैपिंग कोड देखने की अनुमति देता है। इस तरह अगर यह टूट जाता है तो आपको एप्लिकेशन को आग लगने से पहले पता चलेगा (जब मैं तेजी से जाने की कोशिश कर रहा हूं तो मुझे काम का एक टन बचाता है)

1

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

[TestFixture] 
    public class TrannsactionScopeTests 
    { 
     private TransactionScope trans = null; 

     [SetUp] 
     public void SetUp() 
     { 
      trans = new TransactionScope(TransactionScopeOption.Required); 
     } 

     [TearDown] 
     public void TearDown() 
     { 
      trans.Dispose(); 
     } 

     [Test] 
     public void TestServicedSameTransaction() 
     { 
      MySimpleClass c = new MySimpleClass(); 
      long id = c.InsertCategoryStandard("whatever"); 
      long id2 = c.InsertCategoryStandard("whatever"); 
      Console.WriteLine("Got id of " + id); 
      Console.WriteLine("Got id of " + id2); 
      Assert.AreNotEqual(id, id2); 
     } 
    } 
: यहाँ पता चलता है कि कितना आसान है अपने परीक्षण को रोलबैक करने की क्षमता जोड़ने के लिए है कोड का एक सरल टुकड़ा है