क्या (डेटाबेस) एकीकरण परीक्षण खराब हैं?


120

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

मुझे लगता है कि, कुछ मामलों में, एक यूनिट-परीक्षण बस कुछ भी साबित नहीं करता है।

आइए एक उदाहरण के रूप में निम्नलिखित (तुच्छ, भोले) भंडार कार्यान्वयन (PHP में) करें:

class ProductRepository
{
    private $db;

    public function __construct(ConnectionInterface $db) {
        $this->db = $db;
    }

    public function findByKeyword($keyword) {
        // this might have a query builder, keyword processing, etc. - this is
        // a totally naive example just to illustrate the DB dependency, mkay?

        return $this->db->fetch("SELECT * FROM products p"
            . " WHERE p.name LIKE :keyword", ['keyword' => $keyword]);
    }
}

मान लीजिए कि मैं एक परीक्षण में साबित करना चाहता हूं कि यह भंडार वास्तव में विभिन्न दिए गए कीवर्ड से मेल खाने वाले उत्पाद पा सकता है।

एक वास्तविक कनेक्शन वस्तु के साथ एकीकरण परीक्षण के लघु, मैं कैसे जान सकता हूं कि यह वास्तव में वास्तविक प्रश्न उत्पन्न कर रहा है - और यह कि वास्तव में वे प्रश्न जो मुझे लगता है कि मैं क्या करता हूं?

अगर मुझे यूनिट-टेस्ट में कनेक्शन ऑब्जेक्ट को मॉक करना है, तो मैं केवल "यह अपेक्षित क्वेरी उत्पन्न करता है" जैसी चीजों को साबित कर सकता है - लेकिन इसका मतलब यह नहीं है कि यह वास्तव में काम करने वाला है ... अर्थात, शायद यह क्वेरी उत्पन्न कर रहा है। मुझे उम्मीद थी, लेकिन हो सकता है कि वह ऐसा न करे जो मुझे लगता है कि वह करता है।

दूसरे शब्दों में, मैं एक परीक्षण की तरह महसूस करता हूं जो उत्पन्न क्वेरी के बारे में जोर देता है, अनिवार्य रूप से मूल्य के बिना है, क्योंकि यह परीक्षण कर रहा है कि findByKeyword()विधि कैसे लागू की गई थी , लेकिन यह साबित नहीं होता है कि यह वास्तव में काम करता है

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

आप इन जैसी स्थितियों से कैसे निपटेंगे?

क्या इस तरह के मामले में एकीकरण परीक्षण वास्तव में "खराब" हैं?

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


5
पढ़ें agitar.com/downloads/TheWayOfTestivus.pdf , विशेष रूप से पेज 6 "परीक्षण इकाई से अधिक महत्वपूर्ण है"।
डॉक्टर ब्राउन

2
@ user61852 यह वर्णन में "भोली" कहते हैं, हाँ?
mindplay.dk

4
आपका सहकर्मी कैसे निश्चित होगा कि उसका नकली डेटाबेस वास्तविक चीज़ के रूप में व्यवहार करता है?
Thorbjørn Ravn Andersen

12
आप यथार्थवादी होने की कोशिश कर रहे हैं। आपका सहकर्मी नियमों का पालन करने की कोशिश कर रहा है। हमेशा ऐसे परीक्षण लिखें जो मूल्य पैदा करते हैं । समय लेखन परीक्षण बर्बाद न करें जो कि अकल्पनीय होगा, और उन परीक्षणों को न लिखें जो निम्नलिखित में से एक नहीं करते हैं: संभावना बढ़ाएं कि आपका कोड सही है या आपको अधिक बनाए रखने योग्य कोड लिखने के लिए मजबूर करना है।
jpmc26

3
@ mindplay.dk: उस पैराग्राफ में मुख्य वाक्य है "लेकिन किसी हठधर्मिता पर अड़ न जाएं। जो परीक्षा लिखनी है, उसे लिखें।" आपका सहकर्मी लगता है कि हठधर्मिता में फंस गया है। और आपको किसी की आवश्यकता नहीं है। आपको यह समझाते हुए कि परीक्षण क्या है जिसे आपके उदाहरण में लिखने की आवश्यकता है - आप पहले से ही जानते हैं। यह स्पष्ट है कि परीक्षण के लिए यदि आपका डेटाबेस क्वेरी को समझता है, तो आपको वास्तविक डेटाबेस के खिलाफ क्वेरी को चलाना होगा - कोई भी नकली आपको नहीं बता सकता है। यह।
डॉक्टर ब्राउन

जवाबों:


129

आपका सहकर्मी सही है कि यूनिट-टेस्ट की जाने वाली हर चीज यूनिट-टेस्ट की जानी चाहिए, और आप सही हैं कि यूनिट टेस्ट आपको केवल इतनी दूर और आगे नहीं ले जाएंगे, खासकर जब जटिल बाहरी सेवाओं के आसपास सरल रैपर लिख रहे हों।

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

        /\                           --------------
       /  \        UI / End-to-End    \          /
      /----\                           \--------/
     /      \     Integration/System    \      /
    /--------\                           \----/
   /          \          Unit             \  /
  --------------                           \/
  Pyramid (good)                   Ice cream cone (bad)

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

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


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


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

6
सॉफ्टवेयर क्यूए का एक कंट्रोवर्शियल स्कूल, संदर्भ-संचालित परीक्षण आंदोलन, विवादित भाग के लिए समर्पित है कि परीक्षण पिरामिड के रूप में अंगूठे के ऐसे किसी भी उपयोगी सामान्य नियम मौजूद हैं। विशेष रूप से, आंदोलन के सेमिनल ग्रंथ कई उदाहरण देते हैं जहां एकीकरण परीक्षण अन्य प्रकार के परीक्षणों की तुलना में कहीं अधिक मूल्यवान हैं (क्योंकि वे प्रणाली के संदर्भ में परीक्षण करते हैं, एक प्रणाली के रूप में ) ...
dodgethesteamroller

7
... नतीजतन, फाउलर एट अल।, यह तर्क देते हुए कि एकीकरण परीक्षणों और उपयोगकर्ता स्वीकृति परीक्षणों पर कम प्रयास खर्च किए जाने चाहिए क्योंकि वे एक मजबूत और बनाए रखने योग्य तरीके से लिखना बहुत मुश्किल है, वास्तव में सिर्फ एक पूर्व पोस्ट फैक्टो प्रदान कर रहे हैं कि क्यों उन्हें पता नहीं चला कि उच्च स्तर पर अच्छी तरह से कैसे परीक्षण किया जाए।
dodgethesteamroller

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

1
एकीकरण परीक्षणों के लिए पदानुक्रम और unittests के अनुपात पर अत्यधिक अनुशंसित प्रस्तुति: vimeo.com/80533536 बहुत अच्छी तरह से समझाया गया है।
szalski

88

मेरे सहकर्मियों में से एक का कहना है कि एकीकरण परीक्षण सभी प्रकार के बुरे और गलत हैं - सब कुछ यूनिट-परीक्षण होना चाहिए,

यह कहना थोड़ा पसंद है कि एंटीबायोटिक्स खराब हैं - सब कुछ विटामिन के साथ ठीक किया जाना चाहिए।

यूनिट परीक्षण सब कुछ नहीं पकड़ सकते हैं - वे केवल परीक्षण करते हैं कि एक घटक नियंत्रित वातावरण में कैसे काम करता है । एकीकरण परीक्षण सत्यापित करते हैं कि सब कुछ एक साथ काम करता है , जो कि करना मुश्किल है लेकिन अंत में अधिक सार्थक है।

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

एक वास्तविक कनेक्शन वस्तु के साथ एकीकरण परीक्षण के लघु, मैं कैसे जान सकता हूं कि यह वास्तव में वास्तविक प्रश्न उत्पन्न कर रहा है - और यह कि वास्तव में वे प्रश्न जो मुझे लगता है कि मैं क्या करता हूं?

आप डेटाबेस स्तर पर इसका परीक्षण कर सकते हैं । विभिन्न मापदंडों के साथ क्वेरी को चलाएं और देखें कि क्या आपको अपेक्षित परिणाम मिलते हैं। दी गई इसका अर्थ है कि किसी भी परिवर्तन को "सही" कोड में कॉपी / पेस्ट करना। लेकिन यह करता है आप किसी भी अन्य निर्भरता क्वेरी स्वतंत्र परीक्षण करने के लिए अनुमति देते हैं।


क्या आप परीक्षण नहीं करेंगे कि डेटाबेस में कुछ डेटा हैं या नहीं?
ट्यूलेंस कोर्डोवा 20

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

हां - मैंने जो उदाहरण दिया, जैसा कि बताया गया है, तुच्छ है; एक वास्तविक रिपॉजिटरी में जटिल खोज और छँटाई के सभी तरीके हो सकते हैं, जैसे एक क्वेरी बिल्डर का उपयोग करना, आदि
mindplay.dk 22

2
अच्छा जवाब है, लेकिन मैं यह जोड़ना चाहूंगा कि डीबी मेमोरी में होना चाहिए, यह सुनिश्चित करने के लिए कि यूनिट परीक्षण तेज हैं।
B:03овиЈ

3
@ B @овиЈ: दुर्भाग्य से, यह हमेशा संभव नहीं हो सकता है, क्योंकि दुर्भाग्य से वहाँ कोई दो संगत DBs नहीं हैं और उनमें से सभी स्मृति में काम नहीं करते हैं। वाणिज्यिक DB के लिए लाइसेंसिंग मुद्दे भी हैं (आपके पास किसी भी मशीन पर इसे चलाने के लिए लाइसेंस नहीं हो सकता है), ...
Matthieu M.

17

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

यहां विभिन्न प्रकार के परीक्षण के लिए दोष का पता लगाने वाली तालिका दर्शाई गई है।

यहां छवि विवरण दर्ज करें

स्रोत: P.470 में कोड पूरा 2 मैककोनेल द्वारा


5
वह डेटा 1986 में इकट्ठा किया गया था । वह तीस साल पहले की बात है । 1986 में यूनिट परीक्षण वे आज नहीं थे। मुझे इस डेटा पर संदेह होगा। उल्लेख नहीं करने के लिए, इकाई परीक्षण बग का पता लगाने से पहले कभी भी प्रतिबद्ध है , इसलिए यह संदिग्ध है कि उन्हें सूचित किया जाएगा।
रबरडक

3
@ रबरडक यह चार्ट 2006 की किताब का है, और यह 1986, 1996, 2002 के आंकड़ों पर आधारित है (यदि आप ध्यान से देखें)। मैंने स्रोतों में डेटा एकत्रित करने वाले प्रोटोकॉल पर ध्यान नहीं दिया है, मैं यह नहीं कह सकता कि जब उन्होंने एक दोष को ट्रैक करना शुरू किया और यह कैसे बताया गया। क्या यह चार्ट कुछ पुराना हो सकता है? यह हो सकता है। पिछले दिसंबर में मैं एक संगोष्ठी में था, और प्रशिक्षक ने उल्लेख किया कि एकीकरण परीक्षण यूनिट परीक्षणों (2 के कारक, iirc) की तुलना में अधिक बग ढूंढते हैं। यह चार्ट कहता है कि वे उसी के बारे में हैं।
निक एलेविव

13

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

यूनिट टेस्ट

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

इसलिए, एक डेटाबेस के लिए, किसी के पास कुछ होना चाहिए:

IRespository

List<Product> GetProducts<String Size, String Color);

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

एकीकरण टेस्ट

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

  • पर्यावरण स्वास्थ्य स्थिरता तत्परता
  • असली बात को परखना

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

एकीकरण परीक्षण पर्यावरण को मान्य करने और वास्तविक चीज़ों को सुनिश्चित करने के लिए काफी मूल्यवान साबित हो सकते हैं।

एक दोनों होना चाहिए।

  • हर बिल्ड के लिए यूनिट टेस्ट चलाएं।
  • हर तैनाती के लिए एकीकरण परीक्षण चलाएं।

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

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

11

डेटाबेस एकीकरण परीक्षण खराब नहीं हैं। और भी, वे आवश्यक हैं।

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

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

निष्कर्ष

इकाई के सार से आपका क्या विश्वास है , जो आपके एब्सट्रैक्ट रिपॉजिटरी , ईथर ऑब्जेक्ट-रिलेशनल-मैपर , जेनेरिक एक्टिव रिकॉर्ड , थियोरेटिक पर्सिस्टेंस लेयर्स का परीक्षण करता है , जब अंत में आपके उत्पन्न एसक्यूएल में सिंटैक्स त्रुटि होती है?


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

डेटाबेस एकीकरण परीक्षण हालांकि खराब हैं। क्या आपके पास ci / cd लाइन में एक डेटाबेस उपलब्ध है? यह मुझे बहुत जटिल लगता है। डेटाबेस सामान का मज़ाक बनाना और उस का उपयोग करने के लिए अमूर्त की एक परत बनाना बहुत आसान है। इतना ही नहीं एक बहुत अधिक सुंदर समाधान है, यह जितना तेजी से हो सकता है। यूनिट परीक्षणों को तेज करने की आवश्यकता है। अपने डेटाबेस का परीक्षण आपके unittests को काफी स्तर तक धीमा कर देता है कि यह स्वीकार्य नहीं है। जब आप उनमें से हजारों हैं, तब भी Unittests को 10 मिनट नहीं करना चाहिए।
डेविड

@ डेविड क्या आपके पास अपने ci / cd लाइन में एक डेटाबेस उपलब्ध है? यकीन है, यह सुंदर मानक सुविधा है । BTW, मैं इकाई परीक्षणों के बजाय एकीकरण परीक्षणों की वकालत नहीं कर रहा हूँ - मैं इकाई परीक्षणों के संयोजन में एकीकरण परीक्षणों की वकालत कर रहा हूँ । फास्ट यूनिट परीक्षण आवश्यक हैं, लेकिन डेटाबेस बहुत जटिल हैं जो नकली बातचीत के साथ यूनिट परीक्षणों पर भरोसा करते हैं।
el.pescado

@ el.pescado से मुझे असहमत होना है। यदि आपका डेटाबेस संचार अमूर्तता की एक परत के पीछे है, तो यह वास्तव में आसान है। आप बस यह तय कर सकते हैं कि किस वस्तु को वापस करना है। इसके अलावा, तथ्य यह है कि कुछ मानक है यह एक अच्छी बात नहीं है।
डेविड

@ मुझे लगता है कि यह इस बात पर निर्भर करता है कि आप डेटाबेस से कैसे संपर्क करते हैं। क्या यह कार्यान्वयन विस्तार या प्रणाली का महत्वपूर्ण हिस्सा है ? (मैं बाद की ओर झुकाव) । यदि आप डेटाबेस को डेटा के गूंगे भंडारण के रूप में मानते हैं, तो हाँ, आप एकीकरण परीक्षणों के बिना कर सकते हैं। हालाँकि, अगर डेटाबेस में कोई तर्क है - बाधाओं, ट्रिगर, विदेशी कुंजियों, लेनदेन, या आपकी डेटा परत सादे ORM तरीकों के बजाय कस्टम SQL का उपयोग करती है, मुझे लगता है कि यूनिट परीक्षण अकेले पर्याप्त नहीं होंगे।
el.pescado

6

आपको दोनों की आवश्यकता है।

अपने उदाहरण में यदि आप परीक्षण कर रहे थे कि एक निश्चित स्थिति में एक डेटाबेस, जब findByKeywordविधि को चलाया जाता है तो आपको वह डेटा वापस मिल जाता है जिसकी आपको उम्मीद है कि यह एक अच्छा एकीकरण परीक्षण है।

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


6

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

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

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

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

उदाहरण के लिए, यदि आप जानते हैं कि आपका एप्लिकेशन किसी डेटाबेस पर (और संभवतः किसी विशिष्ट डेटाबेस सिस्टम पर) भरोसा करने वाला है, तो इसके लिए डेटाबेस के व्यवहार का मज़ाक उड़ाना अक्सर समय की बर्बादी होगी। डेटाबेस इंजन (विशेष रूप से आरडीबीएमएस) जटिल प्रणाली हैं। SQL की कुछ पंक्तियाँ वास्तव में बहुत काम कर सकती हैं, जिन्हें अनुकरण करना मुश्किल होगा (वास्तव में, यदि आपकी SQL क्वेरी कुछ पंक्तियाँ लंबी है, तो संभावना है कि आपको जावा / PHP / C # / पायथन की कई और लाइनों की आवश्यकता होगी। आंतरिक रूप से समान परिणाम उत्पन्न करने के लिए कोड): आपके द्वारा पहले से ही DB में लागू किए गए तर्क की नकल करने से कोई मतलब नहीं है, और उस परीक्षण कोड की जांच करना अपने आप में एक समस्या बन जाएगा।

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

डेटाबेस को रीसेट करने और परीक्षण डेटा के साथ फिर से खोलने का समय विचार करने का एक पहलू है; आप आम तौर पर उस नकली कोड को लिखने में लगने वाले समय के खिलाफ इसका मूल्यांकन करेंगे (जिसे आपको अंततः बनाए रखना होगा)।

विचार करने के लिए एक और बिंदु आपके आवेदन में डेटाबेस के साथ निर्भरता की डिग्री है।

  • यदि आपका एप्लिकेशन बस एक CRUD मॉडल का अनुसरण करता है, जहां आपके पास अमूर्तता की एक परत है जो आपको कॉन्फ़िगरेशन सेटिंग के सरल साधनों द्वारा किसी भी RDBMS के बीच स्वैप करने की सुविधा देता है, तो संभावना है कि आप एक मॉक सिस्टम के साथ काफी आसानी से काम कर पाएंगे (संभवतः धुंधला हो रहा है) इकाई के बीच की रेखा और इन-मेमोरी आरडीबीएमएस का उपयोग करके एकीकृत परीक्षण)।
  • यदि आपका एप्लिकेशन अधिक जटिल तर्क का उपयोग करता है, तो ऐसा कुछ जो SQL सर्वर, MySQL, PostgreSQL (उदाहरण के लिए) में से किसी एक के लिए विशिष्ट होगा, तो यह आम तौर पर उस विशिष्ट प्रणाली का उपयोग करने वाले परीक्षण के लिए अधिक समझ में आता है।

"आज कई एप्लिकेशन बस काम नहीं करेंगे अगर उनका डेटाबेस सर्वर नीचे चला गया" - यह वास्तव में महत्वपूर्ण बिंदु है!
el.pescado

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

1

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

इसे पूरा करने के लिए, आपको एक एसक्यूएल नियम इंजन को लिखने या एकीकृत करने के लिए पर्याप्त समय और संसाधन खाली करने होंगे, जो गारंटी देगा कि एसक्यूएल बयान को परीक्षण के तहत विषय द्वारा उत्सर्जित किया जाएगा, जिसके परिणामस्वरूप अपेक्षित संचालन होगा।

हालांकि, अक्सर भूल गए और मॉकिंग के लिए कुछ महंगा विकल्प / साथी "वर्चुअलाइजेशन" है

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

अब, एक कह सकता है, आपने एक इकाई परीक्षण को एकीकरण परीक्षण में बदल दिया। यूनिट परीक्षणों और एकीकरण परीक्षणों के बीच वर्गीकृत करने के लिए लाइन खींचने के लिए अलग-अलग विचार हैं। IMHO, "यूनिट" एक मनमानी परिभाषा है और इसे आपकी आवश्यकताओं के अनुरूप होना चाहिए।


1
यह केवल बनाए गए दोहराने वाले बिंदुओं को लगता है और इस पूर्व उत्तर में बताया गया है जो कई घंटे पहले पोस्ट किया गया था
gnat

0

Unit Testsऔर एक दूसरे के लिए ओर्थोगोनलIntegration Tests हैं । वे आपके द्वारा बनाए जा रहे एप्लिकेशन पर एक अलग दृश्य प्रस्तुत करते हैं। आमतौर पर आप दोनों चाहते हैं । लेकिन समय में बिंदु अलग-अलग होता है, जब आप चाहते हैं कि किस तरह के परीक्षण हैं।

सबसे अधिक बार आप चाहते हैं Unit Tests। यूनिट परीक्षण परीक्षण किए जा रहे कोड के एक छोटे हिस्से पर ध्यान केंद्रित करते हैं - जिसे वास्तव में कहा जाता unitहै वह पाठक के लिए छोड़ दिया जाता है। लेकिन ते उद्देश्य सरल है: आपका कोड कब और कहां टूट गया, इस बारे में तेजी से प्रतिक्रिया मिल रही है । उस ने कहा, यह स्पष्ट होना चाहिए, कि एक वास्तविक DB के लिए कॉल एक गैर है

दूसरी ओर, कुछ चीजें हैं, जो केवल डेटाबेस के बिना कठिन परिस्थितियों में जांच की जाने वाली इकाई हो सकती हैं । शायद आपके कोड में एक दौड़ की स्थिति है और DB के लिए एक कॉल का उल्लंघन होता है, unique constraintजिसे केवल तभी फेंक दिया जा सकता है यदि आप वास्तव में इस प्रणाली का उपयोग करते हैं। लेकिन उन प्रकार के परीक्षण महंगे हैं जिन्हें आप (और नहीं करना चाहते) उन्हें जितनी बार चाहें चला सकते हैं unit tests


0

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

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

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

वास्तव में, मुझे लगता है कि व्यवहार प्रेरित डिज़ाइन (BDD) जैसा कुछ है जो डोमेन विशिष्ट भाषा (DSL) के साथ अंत तक परीक्षण करने का प्रयास करता है। हमारे पास .Net दुनिया में SpecFlow है, लेकिन यह ककड़ी के साथ खुले स्रोत के रूप में शुरू हुआ।

https://cucumber.io/

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

स्टैक ओवरफ्लो के अनुसार, नकली वस्तुओं का उपयोग तब किया जाता है जब वास्तविक ऑब्जेक्ट यूनिट टेस्ट में शामिल करने के लिए अव्यावहारिक होते हैं।

https://stackoverflow.com/questions/2665812/what-is-mocking

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

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

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

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

https://www.joelonsoftware.com/2009/01/31/from-podcast-38/


यह इतना स्पष्ट है कि आप इकाई और एकीकरण परीक्षणों के बीच अंतर को नहीं समझते हैं
Bћовић

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

-1

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

सही इकाई परीक्षणों के साथ, आप सैंडबॉक्स की सीमा के भीतर परीक्षण कर रहे हैं और यह स्पष्ट होना चाहिए। यदि किसी डेवलपर ने SQL क्वेरी को QA / PROD में विफल किया है तो इसका मतलब है कि उन्होंने उस समय से पहले एक बार भी इसका परीक्षण नहीं किया था।


+1 के लिए "आप उन्हें नियंत्रित नहीं कर सकते (वे एकीकरण परीक्षण चरण के दौरान पास हो सकते हैं लेकिन उत्पादन में विफल हो सकते हैं")
ट्यूलेंस कोर्डोवा

आप उन्हें संतोषजनक डिग्री तक नियंत्रित कर सकते हैं
el.pescado 21

मुझे आपकी बात सही लगी, लेकिन मुझे लगता है कि यह आज की तुलना में अधिक सच है। ऑटोमेशन और टूल्स (जैसे डॉकर) के साथ आप वास्तव में अपने सभी बाइनरी / सर्वर निर्भरताओं के सेटअप को दोहरा सकते हैं और एकीकरण परीक्षण-सुइट्स के लिए सटीक और मज़बूती से दोहरा सकते हैं। बेशक, हाँ, भौतिक हार्डवेयर (और तृतीय-पक्ष सेवाएँ आदि) विफल हो सकते हैं।
mindplay.dk

5
मैं बिल्कुल सहमत नहीं हूं। आपको (अतिरिक्त) एकीकरण परीक्षण लिखना चाहिए क्योंकि बाह्य निर्भरताएं विफल हो सकती हैं। बाहरी निर्भरता के अपने स्वयं के quirks हो सकते हैं, जो आपको सबसे अधिक संभावना है जब आप सब कुछ नकली करेंगे।
पॉल केर्चर

1
@PaKK अभी भी विचार कर रहा है जो स्वीकार किए जाते हैं, लेकिन मैं उसी निष्कर्ष की ओर झुक रहा हूं।
mindplay.dk
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.