Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. PHP
Code

Laravel में एक बॉस की तरह टेस्ट करें: मॉडल

by
Difficulty:AdvancedLength:LongLanguages:

Hindi (हिंदी) translation by Ashish Rampal (you can also view the original English article)

यदि आप यह सीखने की उम्मीद कर रहे हैं कि टेस्ट फायदेमंद क्यों है, यह आर्टिकल आपके लिए नहीं है. इस ट्यूटोरियल के कोर्स में, मैं यह मानूंगा कि आप पहले से ही इसके फायदे को जानते हैं, और उम्मीद करते हैं की Laravel 4 टेस्ट को कैसे अच्छे से लिखें और ऑर्गेनाइज करें।

Laravel का वर्जन 4 आपको गंभीर इंप्रूवमेंट ऑफर करता है जब आप टेस्टिंग की बात करते हैं, खासतौर पर तब जब हम इसकी पिछली रिलीज के साथ इसका मुकाबला करते हैं। यह इस सीरीज का पहला आर्टिकल है जो यह बताएगा कि Laravel 4 एप्लीकेशन के लिए टेस्ट्स को किस प्रकार लिखें। हम इस सीरीज की शुरुआत मॉडल टेस्टिंग के बारे में बातचीत करके करेंगे।


सेटअप

In-memory डेटाबेस

जब तक कि आप अपने डेटाबेस पर रॉ क्वेरी चला रहे हैं, Laravel आपकी एप्लीकेशन को डेटाबेस अग्नोस्टिक (agnostic) रहने देता है। कुछ साधारण से ड्राइवर परिवर्तित करके, आपकी एप्लीकेशन अब दूसरे DBMS (MySQL, PostgreSQL, SQLite, आदि) के साथ काम कर सकती है। डिफॉल्ट ऑप्शन के साथ, SQLite आपको अजीब, लेकिन फिर भी उपयोगी फीचर ऑफर करता है: in-memory डेटाबेस।

Sqlite के साथ, हम डेटाबेस कनेक्शन को :memory: से सेट कर सकते हैं, जो कि आप के टेस्ट की गति को बहुत अधिक बढ़ा देगा, क्योंकि डाटा बेस हार्ड डिस्क पर मौजूद नहीं है। इसके अलावा, प्रोडक्शन/डेवलपमेंट डेटाबेस कभी भी लेफ्ट-ओवर टेस्ट डाटा के साथ नहीं आएगा, क्योंकि कनेक्शन, :memory:, हमेशा एक खाली डेटाबेस के साथ शुरू होता है।

संक्षेप में: एक in-memory डेटाबेस तेज और साफ-सुथरे टेस्ट की अनुमति देता है।

app/config/testing डायरेक्टरी के अंदर, एक नई फाइल बनाएं, जिसका नाम database.php रखें, और निम्न कंटेंट के साथ उसे भरे:

तथ्य यह है कि database.php कॉन्फ़िगरेशन testing डायरेक्टरी के भीतर रखी गई है, जिसका अर्थ यह है कि इन सेटिंग्स का उपयोग केवल तभी किया जाएगा जब आप टेस्टिंग इन्वायरमेंट में हो (जो Laravel में ऑटोमेटिक रूप से सेट है)। जैसे कि जब आपकी एप्लीकेशन को नॉर्मल तरीके से एक्सेस किया जाता है, in-memory डेटाबेस का प्रयोग नहीं किया जाएगा।

टेस्ट को रन करने से पहले

क्योंकि in-memory डेटाबेस हमेशा खाली रहता है जब कनेक्शन बनाया जाता है, यह महत्वपूर्ण है की हर टेस्ट से पहले डेटाबेस को migrate करें। यह करने के लिए, app/tests/TestCase.php को खोलें और एक क्लास के अंत में निम्नलिखित मेथड को जोड़ें:

नोट: setUp() मेथड को PHPUnit द्वारा हर टेस्ट से पहले एग्जीक्यूट किया जाता है।

यह मेथड डेटाबेस को तैयार करेगा, और Laravel की Mailer क्लास को pretend स्टेटस में परिवर्तित कर देगा। इस तरीके से, Mailer कोई असली का इमेल नहीं भेजेगा जब हम टेस्ट चलाते हैं। इसके बजाय, यह “sent” मैसेज को log कर देगा।

app/tests/TestCase.php को अंतिम रुप देने के लिए, PHPUnit के setUp() मेथड के अंदर prepareForTests() को कॉल करें, जो कि हर टेस्ट से पहले एग्जीक्यूट होगा।

parent::setUp() को ना भूले, क्योंकि हम अपनी पैरंट क्लास के मेथड को ओवरराइट कर रहे हैं।

इस बिंदु पर, app/tests/TestCase.php निम्न कोड की तरह नजर आएगा। याद रखें कि createApplication Laravel द्वारा ऑटोमेटिक तरीके से बना दी जाती है। आपको इसकी चिंता करने की जरूरत नहीं है।

अब, अपने टेस्ट लिखने के लिए, सिर्फ TestCase को एक्सटेंड करें, और डेटाबेस को हर टेस्ट से पहले इनिशियलाइज़ और माइग्रेट कर दिया जाएगा।


टेस्ट

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

इस डेमो एप्लीकेशन के कॉन्टेक्स्ट में एक साधारण ब्लॉग/CMS है, जिनमें यूज़र्स (ऑथेंटिकेशन), पोस्ट्स और स्टैटिक पेजेज शामिल है (जो कि मैन्यू में दिखाएं जाते हैं)।

पोस्ट मॉडल

कृपया ध्यान दें कि मॉडल Eloquent की बजाय, Ardent, क्लास को एक्सटेंड करता है। Ardent एक पैकेज है जो कि आसान वैलिडेशन के लिए बनाया जाता है, मॉडल को सेव करने के लिए ($rules प्रॉपर्टी को देखें)।

इसके बाद, हमारे पास public static $factory ऐरे है। जिसमें FactoryMuff पैकेज की शक्ति है, ताकि टेस्टिंग के दौरान ऑब्जेक्ट बनाने को असिस्ट किया जा सके।

दोनों Ardentx और FactoryMuff Packagist और Composer के द्वारा उपलब्ध है।

हमारे Post मॉडल में, हमारे पास User मॉडल के साथ रिलेशनशिप है, जादुई author मेथड के साथ।

अंत में, हमारे पास एक साधारण मेथड है जोकि तारीख को रिटर्न करता है, “day/month/year” फॉर्मेट में।

पोस्ट टेस्ट

चीजों को ऑर्गेनाइज रखने के लिए, मैंने क्लास को Post मॉडल के साथ app/tests/models/PostTest.php में रख दिया है। हम इन सभी टेस्ट के माध्यम से गुजरेंगे, एक बार में एक सेक्शन।

हम TextCase क्लास को एक्सटेंड करते हैं, जो कि Laravel में PHPUnit टेस्टिंग की रिक्वायरमेंट है। साथ ही, हमारे prepareTests मेथड को ना भूले जो हर टेस्ट से पहले चलाया जाएगा।

यह टेस्ट “optional” है। हम यह टेस्ट कर रहे हैं कि रिलेशनशिप ”Post User से संबंधित है”। यहां हमारे उद्देश्य है की हम FactoryMuff की फंक्शनैलिटी को डेमोंस्ट्रेट करें।

एक बार जब Post क्लास के पास $factory स्टैटिक ऐरे शामिल हो जाए जिसके अंदर ‘author_id’ => ‘factory|User’ हो (मॉडल के सोर्स कोड पर ध्यान दें, जिसे ऊपर दिखाया गया है) FactoryMuff एक नए User को इंस्टेंशिएट करता है जिससे यह इसके एट्रिब्यूट को भरता है, और डेटाबेस में सेव करता है और अंत में Post के author_id एट्रिब्यूट में इसकी id को रिटर्न करता है।

इसे संभव बनाने के लिए, User मोड के $factory ऐरे होना ही चाहिए जो इसकी फील्ड्स को भी डिस्क्राइब करें।

ध्यान दें आप किस प्रकार $post-author का प्रयोग करके User के रिलेशन तक पहुंच सकते हैं। एक उदाहरण के तौर पर, हम $post->author->username तक पहुंच सकते हैं, या किसी अन्य मौजूदा यूजर एट्रिब्यूट तक।

FactoryMuff पैकेज किसी भी आवश्यक रिलेशन को रिस्पेक्टिंग और इंस्टेंशिएट करने के दौरान टेस्ट के उद्देश्य के लिए कंसिस्टेंट ऑब्जेक्ट के रैपिड इंस्टॉलेशन को इनेबल करता है। इस मामले में, जब हम FactoryMuff::create(‘Post’) के साथ Post को बनाते हैं User भी तैयार हो जाता है और उपलब्ध होता है।

खत्म करने के लिए, हम तय करते हैं कि क्या postedAt() मेथड द्वारा रिटर्न की जाने वाली स्ट्रिंग “day/month/year” फॉर्मेट को फॉलो करती है। इस तरह की वेरिफिकेशन के लिए, रेगुलर एक्सप्रेशन का प्रयोग किया जाता है यह जांचने के लिए की क्या \d{2}\/\d{2}\/\d{4} ("2 numbers" + "bar" + "2 numbers" + "bar" + "4 numbers") पैटर्न मिला है।

वैकल्पिक रूप से, हम PHPUnit के assertRegExp मैं का भी प्रयोग कर सकते थे।

इस बिंदु पर, app/tests/models/PostTest.php फाइल इस प्रकार की है:

PS: मैंने टेस्ट के नाम को CamelCase में पढ़ने संबंधित उद्देश्यों के लिए नहीं लिखा है। PSR-1 मुझे माफ करें, पर testRelationWithAuthor इतना पढ़ने योग्य नहीं है जैसा कि मैं व्यक्तिगत तौर पर पसंद करता हूं। आप उस स्टाइल का प्रयोग करने के लिए आजाद हैं जो आप चाहे, बेशक।

पेज मॉडल

हमारे CMS को एक मॉडल की आवश्यकता है जोकि स्टैटिक पेजेस को रिप्रेजेंट कर सके। यह मॉडल निम्न प्रकार से इंप्लीमेंट किया जाता है:

हम यह ऑब्जर्व कर सकते हैं कि स्टैटिक मेथड, renderMenu(), काफी सारे लिंक को सभी मौजूदा पेजों के लिए रेंडर करता है। यह वैल्यू कैश key में सुरक्षित की जाती है, ‘pages_for_menu’। इस प्रकार से, भविष्य में renderMenu() को कॉल करते हैं, असली डेटाबेस पर जाने की कोई भी जरूरत नहीं है। यह हमारी एप्लीकेशन की परफॉर्मेंस में देखने लायक इंप्रूवमेंट उपलब्ध करा सकता है।

हालांकि, यदि एक Page सेव किया जाता है या डिलीट किया जाता है (afterSave() और delete() मेथड्स), कैश की वैल्यू को मिटा दिया जाएगा, इसके परिणाम स्वरुप renderMenu() डेटाबेस की नयी स्टेटस को रिफ्लेक्ट करता है। इसलिए यदि पेज का नाम परिवर्तित होता है, या यदि यह डिलीट होता है, key ‘pages_for_menu’ को कैश से मिटा दिया जाएगा। (Cache::forget(‘pages_for_menu’); )

नोट: मेथड, afterSave(), पूरे Ardent पैकेज के अंदर उपलब्ध है। नहीं तो, यह जरूरी हो जाएगा की save() मेथड को कैश साफ करने के लिए इंप्लीमेंट किया जाए और parent::save(); को कॉल किया जाए

पेज टेस्ट

app/tests/models/PageTest.php मैं, हम निम्नलिखित टेस्ट को लिखेंगे:

एक बार फिर, हमारे पास एक “optional” टेस्ट है ताकि हम रिलेशनशिप को कंफर्म कर सके। क्योंकि रिलेशनशिप Illuminate\Database\Eloquent की रिस्पांसिबिलिटी है, जोकि Laravel के खुद के टेस्ट में पहले ही कवर की जा चुकी है, हमें फिर से एक कंफर्म करने के लिए और टेस्ट लिखने की जरूरत नहीं है की यह कोड वैसे ही काम करेगा जैसी उम्मीद है।

यह Page मॉडल का एक बहुत ही महत्वपूर्ण टेस्ट है। सबसे पहले, for लूप में चार पेज बनाए जाते हैं। इसके बाद, renderMenu() के कॉल के परिणाम को $result वेरिएबल में स्टोर किया जाता है। इस वेरिएबल में एक HTML स्ट्रिंग होनी चाहिए, जिसमें मौजूद पेजों के लिंक होने चाहिए।

foreach लूप यह जांचता हैं कि क्या सभी पेजों के स्लग (url) $result में मौजूद हैं। बस इतना काफी है, क्योंकि HTML को एकदम उसी फॉर्मेट में होना हमारी आवश्यकता के लिए जरूरी नहीं है।

अंत में, हम यह तय करते हैं कि क्या कैश key, pages_for_menu, में कुछ मौजूद है। दूसरे शब्दों में, क्या renderMenu() की कॉल ने कैश में वाकई कुछ डाला है?

इस टेस्ट का उद्देश्य यह पता लगाना है कि, क्या जब नए Page को सेव किया जाता है, तो कैश key ‘pages_for_menu’ खाली है। FactoryMuff::create(‘Page’); अंत में save() मेथड को चलाता है, ताकि यह key, ‘pages_for_menu’ की सफाई को पूरा कर सकें।

पिछले टेस्ट के ही समान, यह पता लगाता है कि क्या ‘pages_for_menu’ Page को डिलीट करने के बाद यह पूरी तरह से खाली है।

आपके PageTest.php को इस प्रकार का नजर आना चाहिए:

यूजर मॉडल

पिछले दिखाए गए मॉडल से संबंधित, अब हमारे पास User है। यहां इस मॉडल के कोड को दिया गया है:

इस मॉडल में टेस्ट नदारद हैं।

हम यह निरिक्षण कर सकते हैं की, रिलेशनशिप के एक एक्सेप्शन के साथ (जोकि टेस्ट में मददगार हो सकता है), यहां कोई भी अन्य मेथड इंप्लीमेंट नहीं किया गया। ऑथेंटिकेशन के बारे में क्या? वेल, Confide पैकेज का प्रयोग पहले ही इसके लिए इंप्लीमेंटेशन और टेस्ट को उपलब्ध कराता है।

Zizaco\Confide\ConfideUser के लिए टेस्ट ConfideUserTest.php में मौजूद है।

क्लास की रिस्पांसिबिलिटी को निर्धारित करना महत्वपूर्ण है इससे पहले कि आप अपने टेस्ट को लिखें। किसी User के “reset the password” के ऑप्शन का टेस्ट करना अनावश्यक होगा। ऐसा इसलिए है क्योंकि टेस्ट की उचित जिम्मेदारी Zizaco\Confide\ConfideUser; के अंदर है User में नहीं।

डाटा वैलिडेशन टेस्ट के लिए भी यही सही है। पैकेज के रूप में, Ardent, इस जिम्मेदारी को संभालता है, फंक्शनैलिटी को फिर से टेस्ट करने का कोई मतलब नहीं है।

संक्षेप में: अपने टेस्ट को साफ और संगठित रखें। हर एक क्लास की उचित जिम्मेदारी निर्धारित करें, और वही टेस्ट करें जो इनकी जिम्मेदारी है।


निष्कर्ष

Running Tests

एक डेटाबेस के विरुद्ध टेस्ट एग्जीक्यूट करने के लिए in-memory का उपयोग एक अच्छा अभ्यास है। कुछ पैकजों जैसे कि Ardent, FactoryMuff और Confide से मदद मिलने का धन्यवाद, टेस्ट को साफ और ऑब्जेक्टिव रखते हुए आप अपने मॉडल में कोड की मात्रा को कम कर सकते हैं।

इस आर्टिकल के सीक्वल में, हम Controller टेस्टिंग की समीक्षा करेंगे। साथ बने रहे!

अभी भी Laravel 4 के साथ शुरू कर रहे हैं, तो हमें आपको आवश्यक बातें सिखाने का मौका दें!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.