यूनिट टेस्टिंग और पायथन



मेरा नाम वादिम है, मैं Mail.Ru सर्च में एक प्रमुख डेवलपर हूं। मैं इकाई परीक्षण में अपना अनुभव साझा करूंगा। लेख में तीन भाग होते हैं: पहले में मैं आपको बताऊंगा कि हम आम तौर पर इकाई परीक्षण की सहायता से क्या हासिल करते हैं; दूसरा भाग उन सिद्धांतों का वर्णन करता है जिनका हम अनुसरण करते हैं; और तीसरे भाग से आप सीखेंगे कि उल्लिखित सिद्धांतों को पायथन में कैसे लागू किया गया है।

लक्ष्यों


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

हमारी परियोजनाओं में, हम कई लक्ष्यों का पीछा करते हैं।

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

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

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

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

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

सिद्धांतों


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

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

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

किसी भी परीक्षक से बात करें: वह आपको बताएगा कि मैन्युअल परीक्षण के साथ वह हमेशा एक कार्यान्वयन की कल्पना करता है। अपने अनुभव से, वह पूरी तरह से समझता है कि प्रोग्रामर आमतौर पर कहां गलती करते हैं। परीक्षक सब कुछ चेक नहीं करता है, पहले 5 दर्ज कर रहा है, फिर 6, फिर 7. वह 5, एबीसी, -7 की जांच करता है, और संख्या 100 वर्ण है, क्योंकि वह जानता है कि इन मूल्यों के लिए कार्यान्वयन भिन्न हो सकते हैं, लेकिन 6 और 7 के लिए यह संभावना नहीं है। ।

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

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

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

पायथन कार्यान्वयन


हम xUnit परिवार से मानक यूनिटेस्ट लाइब्रेरी का उपयोग करते हैं। कहानी यह है: स्मॉलटॉक भाषा थी, और इसमें सुन्न लाइब्रेरी थी। सभी ने इसे पसंद किया, वे इसकी नकल करने लगे। लाइब्रेरी को जावा में जूनिट नाम से आयात किया गया था, C ++ में से CUUnit नाम से और रूबी में RUnit (तब इसका नाम बदलकर RSpec) कर दिया गया। अंत में, जावा से, पुस्तकालय "बिना नाम के" पायथन में "स्थानांतरित" हो गया। और उन्होंने इसे इतना शाब्दिक रूप से आयात किया कि कैमलकेज़ भी बने रहे, हालांकि यह पीईपी 8 के अनुरूप नहीं है।

XUnit के बारे में एक अद्भुत पुस्तक है, "xUnit टेस्ट पैटर्न"। यह बताता है कि इस परिवार के ढांचे के साथ कैसे काम किया जाए। पुस्तक का एकमात्र दोष इसका आकार है: यह विशाल है, लेकिन लगभग 2/3 सामग्री पैटर्न का एक कैटलॉग है। और पुस्तक का पहला तीसरा भाग अद्भुत है, यह आईटी की सबसे अच्छी पुस्तकों में से एक है जो मुझे मिली है।

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



सेटअप


सबसे कठिन और दिलचस्प चरण। सिस्टम को उसकी मूल स्थिति में लाना जिससे आप उसका परीक्षण करना चाहते हैं, बहुत मुश्किल हो सकता है। और सिस्टम की स्थिति मनमाने ढंग से जटिल हो सकती है।

जब तक आपके फ़ंक्शन को कॉल किया जाता है, तब तक कई घटनाएं हो सकती थीं, स्मृति में एक लाख ऑब्जेक्ट बनाए जा सकते थे। आपके सॉफ़्टवेयर से जुड़े सभी घटकों में - फ़ाइल सिस्टम में, डेटाबेस, कैश - कुछ पहले से ही स्थित है, और फ़ंक्शन केवल इस वातावरण में काम कर सकता है। और अगर पर्यावरण तैयार नहीं होता है, तो फ़ंक्शन की क्रियाएं अर्थहीन होंगी।

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

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

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

फ़ाइल सिस्टम के लिए, फिर इसे बनाना काफी सरल है। io.StringIO और io.BytesIO साथ एक io मॉड्यूल है। आप फ़ाइल जैसी वस्तुएं बना सकते हैं जो वास्तव में डिस्क तक नहीं पहुंचती हैं। लेकिन अगर अचानक यह आपके लिए पर्याप्त नहीं है, तो अस्थायी फ़ाइलों, निर्देशिकाओं, नामित फ़ाइलों, कुछ भी के लिए संदर्भ प्रबंधकों के साथ एक अद्भुत टेंपरेचर मॉड्यूल है। Tempfile एक सुपर मॉडल है यदि किसी कारण से IO ने आपको फिट नहीं किया।

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

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

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

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

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

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

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

नतीजतन, कोड में केवल एक अंतिम पंक्ति बनी हुई है: user = UserFactory() । उपयोगकर्ता बनाया गया है, और आप उसके साथ काम कर सकते हैं, क्योंकि हुड के तहत उसने वह सब कुछ उत्पन्न किया जिसकी आवश्यकता है। यदि आप चाहें, तो आप मैन्युअल रूप से कुछ कॉन्फ़िगर कर सकते हैं।

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

व्यायाम


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

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

सत्यापित करें


इस स्तर पर, हम स्व-लिखित अभिक्रियाओं का उपयोग करते हैं, यहां तक ​​कि एकल-पंक्ति वाले भी। यदि आप परीक्षण में फ़ाइल के अस्तित्व का परीक्षण करते हैं, तो इसके बजाय self.assertTrue(file_exists(f)) बजाय self.assertTrue(file_exists(f)) लिखने की सलाह देता self.assertTrue(file_exists(f)) not file exists । होलीवर इसके साथ जुड़ा हुआ है: क्या मुझे कैमेलकेस का उपयोग जारी रखना चाहिए, जैसे कि यूनिटेस्ट में, या मुझे पीईआर 8 का पालन करना चाहिए? मेरे पास कोई जवाब नहीं है। यदि आप PEP 8 का पालन करते हैं, तो परीक्षण कोड में CamelCase और snake_case से एक गड़बड़ होगी। और यदि आप CamelCase का उपयोग करते हैं, तो यह PEP 8 के अनुरूप नहीं है।

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

निष्कर्ष


लेखों और किताबों पर बिना शर्त भरोसा न करें। यदि आपको लगता है कि वे गलत हैं, तो संभव है कि यह वास्तव में ऐसा हो।

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

कारखानों पर ध्यान दो। यह एक बहुत ही दिलचस्प पैटर्न है।

PS मैं आपको अपने लेखक के टेलीग्राम चैनल को पाइथन - @pythonetc में प्रोग्रामिंग के लिए आमंत्रित करता हूं।

Source: https://habr.com/ru/post/hi418929/


All Articles