मेरी "वाह, मुझे नहीं पता था कि!" मजाक के साथ पल

सभी को नमस्कार! इस गुरुवार को जावास्क्रिप्ट डेवलपर पाठ्यक्रम बंद हो जाता है। इस संबंध में, हमने एक और दिलचस्प सामग्री के अनुवाद को साझा करने का निर्णय लिया। अच्छी पढाई हो।



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

इसलिए, मैं अपने कुछ पसंदीदा जेस्ट ट्रिक्स शेयर करने जा रहा हूं जो आप में से कुछ पहले से ही जानते होंगे क्योंकि आप डॉक्यूमेंटेशन को पढ़ते हैं और मुझे पसंद नहीं करते हैं (शर्म की बात है), लेकिन मुझे उम्मीद है कि यह उन लोगों की मदद करता है जो सिर्फ इसके माध्यम से जल्दी से भाग गए !

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

# 1 .toBe बनाम .toEqual


पहले, ये सभी कथन मुझे सामान्य लगे:

expect('foo').toEqual('foo') expect(1).toEqual(1) expect(['foo']).toEqual(['foo']) 

समानता बयानों (to.equal) के लिए ची के उपयोग के आधार पर, यह सिर्फ प्राकृतिक है। वास्तव में, जेस्ट शिकायत नहीं करेगा, और ये बयान हमेशा की तरह गुजरते हैं।

हालाँकि, Jest में .toBe और .toEqual हैं। पहले का उपयोग Object.is का उपयोग करते हुए समानता का दावा करने के लिए किया जाता है, और दूसरा वस्तुओं और सरणियों की गहरी तुलना प्रदान करने के लिए किया जाता है। .toEqual में Object.is का उपयोग करने के लिए एक कमबैक है यदि यह पता चला है कि आपको एक गहरी तुलना की आवश्यकता नहीं है, जैसे कि आदिम मूल्यों के लिए समानता का दावा करना, जो बताता है कि पिछला उदाहरण बहुत अच्छा क्यों था।

 expect('foo').toBe('foo') expect(1).toBe(1) expect(['foo']).toEqual(['foo']) 

इस तरह, आप .toEqual का उपयोग करके सभी if-else को छोड़ सकते हैं। यदि आप पहले से ही जानते हैं कि आप किन मूल्यों का परीक्षण कर रहे हैं।
एक सामान्य गलती यह है कि आप .toBe का उपयोग करेंगे आदिम मूल्यों की समानता पर जोर देते हैं।

 expect(['foo']).toBe(['foo']) 

यदि आप .toBe के क्रैश होने पर स्रोत कोड को देखते हैं, तो यह निर्धारित करने का प्रयास करेगा कि क्या आपने वास्तव में .to फ़ंक्शन का उपयोग करके फ़ंक्शन को कॉल करके यह त्रुटि की है। यह आपके परीक्षण का अनुकूलन करते समय एक अड़चन हो सकती है।

यदि आप सुनिश्चित हैं कि आप आदिम मूल्यों का उपयोग कर रहे हैं, तो आपके कोड को अनुकूलन उद्देश्यों के लिए पुनर्गठित किया जा सकता है:

 expect(Object.is('foo', 'foo')).toBe(true) 

प्रलेखन में अधिक जानकारी।

# २ अधिक उपयुक्त तुलना


तकनीकी रूप से, आप किसी भी मान को मान्य करने के लिए .toBe का उपयोग कर सकते हैं। जेस्ट के साथ, आप अपने परीक्षण को और अधिक पठनीय बनाने के लिए कुछ तुलनात्मक टूल का उपयोग कर सकते हैं (और कुछ मामलों में कम)।

 // expect([1,2,3].length).toBe(3) // expect([1,2,3]).toHaveLength(3) const canBeUndefined = foo() // expect(typeof canBeUndefined !== 'undefined').toBe(true) // expect(typeof canBeUndefined).not.toBe('undefined') // expect(canBeUndefined).not.toBe(undefined) // expect(canBeUndefined).toBeDefined() class Foo { constructor(param) { this.param = param } // expect(new Foo('bar') instanceof Foo).toBe(true) // expect(new Foo('bar')).toBeInstanceOf(Foo) 

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

# 3 उपयोगकर्ता इंटरफ़ेस के बिना तत्वों पर स्नैपशॉट परीक्षण


आपने जेस्ट में स्नैपशॉट परीक्षण के बारे में सुना होगा, जहां यह आपके उपयोगकर्ता इंटरफ़ेस तत्वों में परिवर्तन को ट्रैक करने में मदद करता है। लेकिन स्नैपशॉट के साथ परीक्षण वहाँ बंद नहीं करता है।

इस उदाहरण पर विचार करें:

 const allEmployees = getEmployees() const happyEmployees = giveIncrementByPosition(allEmployees) expect(happyEmployees[0].nextMonthPaycheck).toBe(1000) expect(happyEmployees[1].nextMonthPaycheck).toBe(5000) expect(happyEmployees[2].nextMonthPaycheck).toBe(4000) // ...etc 

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

 const allEmployees = getEmployees() const happyEmployees = giveIncrementByPosition(allEmployees) expect(happyEmployees).toMatchSnapshot() 

जब भी रिग्रेशन होता है, आपको पता होता है कि नोड में कौन सा पेड़ छवि से मेल नहीं खाता है।

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

बेशक, परीक्षण स्नैपशॉट तक सीमित नहीं है। पूरा प्रलेखन पढ़ें।

# ४ description.each और test.each पर जाएं


क्या आपने कभी एक परीक्षण लिखा है जो कुछ हद तक इसी के समान है?

 describe('When I am a supervisor', () => { test('I should have a supervisor badge', () => { const employee = new Employee({ level: 'supervisor' }) expect(employee.badges).toContain('badge-supervisor') }) test('I should have a supervisor level', () => { const employee = new Employee({ level: 'supervisor' }) expect(employee.level).toBe('supervisor') }) }) describe('When I am a manager', () => { test('I should have a manager badge', () => { const employee = new Employee({ level: 'manager' }) expect(employee.badges).toContain('badge-manager') }) test('I should have a manager level', () => { const employee = new Employee({ level: 'manager' }) expect(employee.level).toBe('manager') }) }) 

यह नीरस और दिनचर्या है, है ना? बहुत सारे मामलों के साथ ऐसा करने की कल्पना करें।
test.each और test.each आप कोड को निम्न प्रकार से संपीड़ित कर सकते हैं:

 const levels = [['manager'], ['supervisor']] const privileges = [['badges', 'toContain', 'badge-'], ['level', 'toBe', '']] describe.each(levels)('When I am a %s', (level) => { test.each(privileges)(`I should have a ${level} %s`, (kind, assert, prefix) => { const employee = new Employee({ level }) expect(employee[kind])[assert](`${prefix}${level}`) }) }) 

हालाँकि, मुझे अभी तक अपने स्वयं के परीक्षण में इसका उपयोग करना है, क्योंकि मैं अपने परीक्षण को विस्तृत करना पसंद करता हूं, लेकिन मुझे लगा कि यह एक दिलचस्प चाल होगी।

तर्कों पर अधिक विवरण के लिए प्रलेखन देखें (स्पॉइलर: टेबल सिंटैक्स वास्तव में अच्छा है)।

# 5 वैश्विक कार्यों की एकल नकल


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

 function foo () { return Date.now() } expect(foo()).toBe(Date.now()) // This would throw occasionally: // expect(received).toBe(expected) // Object.is equality // // Expected: 1558881400838 // Received: 1558881400837 


अंत में, आपको वैश्विक दिनांक ऑब्जेक्ट को फिर से परिभाषित करना होगा ताकि यह सुसंगत और प्रबंधनीय हो:

 function foo () { return Date.now() } Date.now = () => 1234567890123 expect(foo()).toBe(1234567890123) // 

हालांकि, यह बुरा अभ्यास माना जाता है, क्योंकि परीक्षणों के बीच पुनर्वित्त बनाए रखा जाता है। Date.now पर आधारित कोई अन्य टेस्ट नहीं होने पर आप इस पर ध्यान नहीं देंगे, लेकिन यह लीक भी हो जाएगा।

 test('First test', () => { function foo () { return Date.now() Date.now = () => 1234567890123 expect(foo()).toBe(1234567890123) // }) test('Second test', () => { function foo () { return Date.now() expect(foo()).not.toBe(1234567890123) // ??? }) 

मैं इसे "दरार" करता था ताकि यह लीक न हो:

 test('First test', () => { function foo () { return Date.now() const oriDateNow = Date.now Date.now = () => 1234567890123 expect(foo()).toBe(1234567890123) // Date.now = oriDateNow }) test('Second test', () => { function foo () { return Date.now() expect(foo()).not.toBe(1234567890123) // as expected }) 

हालांकि, ऐसा करने के लिए एक बेहतर, कम हैकर तरीका है:

 test('First test', () => { function foo () { return Date.now() jest.spyOn(Date, 'now').mockImplementationOnce(() => 1234567890123) expect(foo()).toBe(1234567890123) // }) test('Second test', () => { function foo () { return Date.now() expect(foo()).not.toBe(1234567890123) // as expected }) 

इस प्रकार, jest.spyOn वैश्विक दिनांक ऑब्जेक्ट का अनुसरण करता है। यह केवल एक कॉल के लिए अब फ़ंक्शन के कार्यान्वयन की नकल करता है। बदले में यह बाकी परीक्षणों के लिए Date.now बरकरार रहेगा।

जेस्ट में स्टब्स पर निश्चित रूप से अधिक जानकारी है। अधिक विवरण के लिए पूर्ण प्रलेखन देखें।

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

इसके अलावा, यदि आप अक्सर जेस्ट का उपयोग करते हैं, तो मैजेस्टिक की जांच करें, जो जेस्ट के लिए एक जीयूआई-मुक्त जीयूआई है, जो उबाऊ टर्मिनल उत्पादन के लिए एक बहुत अच्छा विकल्प है। मुझे यकीन नहीं है कि लेखक dev.to में है, लेकिन फिर भी इस व्यक्ति के लिए सम्मान है।

हमेशा की तरह, आपके ध्यान के लिए धन्यवाद!

वह सब है। कोर्स पर मिलते हैं।

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


All Articles