49

मैं पहली बार एक नई परियोजना की शुरूआत में हूं और (गैसपी!) पहली बार जब मैं अपनी परियोजना में यूनिट परीक्षण शामिल करने की कोशिश कर रहा हूं।डेटाबेस कॉल के लिए यूनिट परीक्षण कैसे लिखें

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

public DataTable ExecuteQuery(SqlConnection ActiveConnection, string Query, SqlParameterCollection Parameters) 
{ 
    DataTable resultSet = new DataTable(); 
    SqlCommand queryCommand = new SqlCommand(); 
    try 
    { 
     queryCommand.Connection = ActiveConnection; 
     queryCommand.CommandText = Query; 

     if (Parameters != null) 
     { 
      foreach (SqlParameter param in Parameters) 
      { 
       queryCommand.Parameters.Add(param); 
      } 
     } 

     SqlDataAdapter queryDA = new SqlDataAdapter(queryCommand); 
     queryDA.Fill(resultSet); 
    } 
    catch (Exception ex) 
    { 
     //TODO: Improve error handling 
     Console.WriteLine(ex.Message); 
    } 

    return resultSet; 
} 

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

पहला सवाल शायद सबसे जटिल है: इस तरह की एक स्थिति में क्या करना चाहिए मैं भी परीक्षण?

एक बार है कि बस गए है या नहीं, डेटाबेस घटकों को नकली या वास्तविक DB के खिलाफ परीक्षण करने की कोशिश करने के लिए का सवाल आता है।

उत्तर

37

आप क्या परीक्षण कर रहे हैं?

तीन संभावनाएं, कर रहे हैं मेरे सिर के ऊपर से:

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

इस मामले में, आपको डेटाबेस से कनेक्ट करने की आवश्यकता नहीं है; आपको बस एक यूनिट परीक्षण की आवश्यकता है जो एक नकली के साथ डेटाबेस (या इंटरमीडिएट परत, उदाहरण के लिए, जेडीबीसी, (एन) हाइबरनेट, iBatis) को प्रतिस्थापित करता है।

बी। आप एसक्यूएलएक्टिक शुद्धता (जेनरेट) एसक्यूएल का परीक्षण कर रहे हैं।

इस मामले में, क्योंकि एसक्यूएल बोलियों भिन्न होते हैं, तो आपको (आपके RDBMS के सभी quirks नकली के प्रयास से (संभवतः उत्पन्न) अपने आरडीबीएमएस, का सही संस्करण के खिलाफ एसक्यूएल चलाना चाहते हैं और इतना है कि किसी भी आरडीबीएमएस उन्नयन उस परिवर्तन कार्यक्षमता को आपके परीक्षणों द्वारा पकड़ा जाता है)।

सी आप अपने एसक्यूएल, यानी, कि किसी दिए गए आधार रेखा डेटासेट के लिए, अपने परिचालन (तक पहुँचता है/चयन और म्यूटेशन/आवेषण और अपडेट) की अर्थ शुद्धता की उम्मीद नई डाटासेट परीक्षण कर रहे हैं उत्पादन।

के लिए, आप तकनीक का उपयोग कर dbunit की तरह कुछ, या संभवतः डेटाबेस में पूरी तरह से अपने परीक्षण करना (जो आप एक आधारभूत स्थापित करने के लिए और एक परिणाम के एक उम्मीद परिणाम सेट करने के लिए सेट की तुलना की अनुमति देता है) का उपयोग करना चाहते हैं, मैं यहां रेखांकित करता हूं: Best way to test SQL queries

1

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

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

5

भगवान के प्यार के लिए, लाइव, पहले से आबादी वाले डेटाबेस के खिलाफ परीक्षण न करें। लेकिन आप उसे जानते थे।

सामान्य तौर पर आप पहले से ही डेटा किस तरह प्रत्येक क्वेरी को पुनः प्राप्त करने के लिए, आप, उपयोगकर्ताओं को प्रमाणीकृत करने फोनबुक/संगठन चार्ट प्रविष्टियों, या जो कुछ भी देख रहे हैं कि क्या हो रहा है की एक विचार है। आप जानते हैं कि आप किस क्षेत्र में रुचि रखते हैं, और आप जानते हैं कि उन पर बाधाएं मौजूद हैं (उदा।, UNIQUE, NOT NULL, और इसी तरह)। आप इकाई को अपने कोड का परीक्षण कर रहे हैं जो डाटाबेस के साथ इंटरैक्ट करता है, डेटाबेस नहीं, इसलिए उन कार्यों का परीक्षण करने के तरीके के बारे में सोचें। यदि फ़ील्ड के लिए NULL होना संभव है, तो आपके पास एक परीक्षण होना चाहिए जो सुनिश्चित करता है कि आपका कोड NULL मानों को सही तरीके से संभालता है। अपने क्षेत्रों में से एक एक स्ट्रिंग है (CHAR, VARCHAR, TEXT, & ग), परीक्षण सुनिश्चित करें कि आप बच गए पात्रों संभाल रहे हैं सही ढंग से किया जाना है।

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

* अवांछनीय, दुर्भावनापूर्ण या अमान्य इनपुट सहित।

+1

दरअसल - आप एक दिलचस्प बिंदु लाते हैं। क्या ऐसे उपकरण हैं जो डेटाबेस परत के लिए इकाई परीक्षणों को स्पष्ट रूप से बनाने में सहायता करते हैं? (दूसरे शब्दों में, इकाई परीक्षण procs खुद को?) –

+1

आह - ऐसा लगता है मेरे सवाल पूछा गया है और उत्तर दिया, यहाँ: http://stackoverflow.com/questions/754527/best-way-to-test-sql- प्रश्नों के लिए/754,570 # 754,570 –

2

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

ठीक है, लेकिन आप डेटाबेस एक्सेस परत को यूनिट-टेस्ट कैसे करते हैं? मुझे इस पुस्तक से सलाह पसंद है: xUnit Test Patterns (लिंक पुस्तक के "परीक्षण डब्ल्यू/डीबी" अध्याय को इंगित करता है।चाबियाँ हैं:

  • उपयोग राउंड ट्रिप परीक्षण क्योंकि वे अपने 'असली' इकाई की तुलना में बहुत धीमा चलेगा
  • , अपने डेटा का उपयोग परीक्षण स्थिरता में भी कई परीक्षण नहीं लिखते परीक्षण
  • अगर आप एक वास्तविक डेटाबेस के साथ परीक्षण से बच सकते हैं, डेटाबेस के बिना परीक्षण
1

यह ठीक से करने के लिए हालांकि आपको कुछ निर्भरता इंजेक्शन (डीआई) का उपयोग करना चाहिए, और .NET के लिए कई हैं। मैं वर्तमान में एकता फ्रेमवर्क का उपयोग कर रहा हूं लेकिन कुछ ऐसे हैं जो आसान हैं।

यहाँ इस विषय पर इस साइट से एक लिंक है, लेकिन अन्य हैं: Dependency Injection in .NET with examples?

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

चूंकि आपने सर्वोत्तम प्रथाओं के बारे में पूछा है, यह एक होगा, आईएमओ।

फिर, जब तक आपको आवश्यकता नहीं है, डीबी पर नहीं जा रहा है, जैसा कि सुझाव दिया गया है।

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

संपादित करें: डेटाबेस यूनिट परीक्षण द्वारा मेरा मतलब यह है, क्योंकि इसे कुछ सेटअप, परीक्षण और टियरडाउन करने के लिए केवल टी-एसक्यूएल का उपयोग करने के लिए डिज़ाइन किया गया है। http://msdn.microsoft.com/en-us/library/aa833233%28VS.80%29.aspx

+0

लेकिन इस मामले में, आप अपने परीक्षण, विफल जब वे अप्रत्याशित डेटा मुठभेड़, ताकि आप अपने घटक हालत ठीक से संभाल पुनर्लेखन कर सकते हैं। – MusiGenesis

+0

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

19

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

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

3

आप इकाई को छोड़कर सब कुछ जांच सकते हैं: queryDA.Fill (परिणामसेट);

जैसे ही आप queryDA निष्पादित करते हैं। भरें (परिणामसेट), आपको या तो डेटाबेस को नकली/नकली करना होगा, या आप एकीकरण परीक्षण कर रहे हैं।

मैं एक के लिए, एकीकरण परीक्षण को बुरा होने के रूप में नहीं देखता, यह सिर्फ इतना है कि यह एक अलग तरह की बग पकड़ लेगा, झूठी नकारात्मकताओं और झूठी सकारात्मकताओं के अलग-अलग मतभेद हैं, अक्सर ऐसा करने की संभावना नहीं है क्योंकि यह बहुत धीमी है।

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

असल में डेटासेट भरना आपके डेटाबेस का परीक्षण कर रहा है, जो आपके डीएएल के दायरे से बाहर एक फ्लैकी घटक है।

7

एक यूनिट परीक्षण का पूरा बिंदु अलगाव में एक इकाई (duh) का परीक्षण करें। एक डेटाबेस कॉल के पूरे मुद्दे एक और इकाई (डेटाबेस) के साथ एकीकृत करने के लिए है। Ergo: यह यूनिट परीक्षण डेटाबेस कॉल के लिए समझ में नहीं आता है।

हालांकि, आपको एकीकरण परीक्षण डेटाबेस कॉल करना चाहिए (और यदि आप चाहें तो यूनिट परीक्षण के लिए आप उसी टूल का उपयोग कर सकते हैं)।

0

JDBC आधारित परियोजना पर, JDBC कनेक्शन, मज़ाक उड़ाया जा सकता है ताकि परीक्षण प्रत्येक परीक्षण का मामला अलग-थलग (कोई डेटा संघर्ष) के साथ, लाइव आरडीबीएमएस बिना क्रियान्वित किया जा सकता।

यह सत्यापित करने की अनुमति देता है, दृढ़ता कोड उचित प्रश्न/पैरामीटर (जैसे https://github.com/playframework/playframework/blob/master/framework/src/anorm/src/test/scala/anorm/ParameterSpec.scala) पास करता है और अपेक्षित के रूप में जेडीबीसी परिणाम (पार्सिंग/मैपिंग) को संभालता है ("डेटाबेस से कुछ डेटा निकालने के लिए सभी आवश्यक बिट्स और टुकड़ों को लेता है, और डेटाटेबल ऑब्जेक्ट में डेटा देता है ")।

जेओयूक्यू या एक्रॉली जैसे फ्रेमवर्क का उपयोग https://github.com/cchantep/acolyte के लिए किया जा सकता है।

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