2010-03-06 16 views
13

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

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

मैं कुछ समाधान पता लगाने के लिए कोशिश कर रहा है, और यहाँ है मैं अब तक क्या पाया है:

  • परीक्षण स्कीमा एक बार आबादी है, और प्रत्येक परीक्षा के अंत में परिवर्तन रोलबैक।

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

  • नकली डेटाबेस जहां संभव

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

  • एक ही सिस्टम चलाने के लिए, लेकिन डंप और RAMFS

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

    मैं इसका परीक्षण नहीं कर सकता क्योंकि यद्यपि मैं ओएसएक्स पर हूं और जो कुछ मैं देख सकता हूं, वहां ramfs समर्थन नहीं है।

आसपास SQLite का उपयोग कर की तरह कुछ अन्य विकल्प हैं, लेकिन इस के रूप में हम कुछ PostgreSQL विशिष्ट एक्सटेंशन पर निर्भर करते हैं हमारे लिए एक विकल्प नहीं है।

हल्प! :)

+8

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

उत्तर

7

Working Effectively with Legacy Code में, माइकल पंख राईट (पृ। 10)

ईकाई परीक्षण तेजी से चलाते हैं। यदि वे तेजी से नहीं चलते हैं, तो वे यूनिट परीक्षण नहीं हैं।

अन्य प्रकार के परीक्षण अक्सर यूनिट परीक्षण के रूप में मास्करेड होते हैं। एक परीक्षण एक यूनिट परीक्षण नहीं है यदि:

  1. यह डेटाबेस से बात करता है।
  2. यह एक नेटवर्क भर में संचार करता है।
  3. यह फ़ाइल सिस्टम को छूता है।
  4. आपको इसे चलाने के लिए अपने पर्यावरण (जैसे कॉन्फ़िगरेशन फ़ाइलों को संपादित करना) में विशेष चीजें करना है।

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

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

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

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

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

+0

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

7

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

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

संपादित

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

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

संपादित दूसरा

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

+0

निश्चित रूप से, लेकिन किसी बिंदु पर हमें परीक्षण करने की आवश्यकता है कि वास्तविक डेटाबेस के साथ बातचीत करता है, और यह अभी भी एक समस्या है कि हम इसे तेजी से चलाने के लिए कैसे प्राप्त करते हैं – ocharles

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