क्या होगा अगर टेस्ट खुद लिखे जाएं? प्रॉपर्टी-आधारित परीक्षण से परिचय
\n\nक्या आपने कभी कोई यूनिट टेस्ट लिखा, उसे चलाया, हरी टिक पाई, और एक महीने बाद उसी फंक्शन में एक बग पाया? परिचित लगता है? क्लासिकल यूनिट टेस्ट ऐसे हैं जैसे सिर्फ एक नोट को देखकर यह जांचना कि आपका बटुआ खाली नहीं है। आप एक विशिष्ट परिदृश्य, इनपुट डेटा का एक सेट जांचते हैं। क्या होगा अगर मैं आपसे कहूं कि एक तरीका है जिससे कंप्यूटर खुद हजारों अलग-अलग परिदृश्य बना सकता है और जांच सकता है कि आपका कोड टूटता है या नहीं?
\n\nयह कल्पना नहीं है। यह है JavaScript में प्रॉपर्टी-आधारित परीक्षण (या गुणों के आधार पर परीक्षण)। "अगर 2 और 3 दें, तो 5 मिलेगा" लिखने के बजाय, आप अपने फंक्शन का एक गुण (property) बताते हैं: "किन्हीं दो संख्याओं के लिए, जोड़ का परिणाम हमेशा एक ऐसी संख्या होगी जो प्रत्येक जोड़े जाने वाली संख्या से बड़ी या बराबर होती है।" और टेस्ट वातावरण सैकड़ों यादृच्छिक संख्या जोड़े उत्पन्न करता है, इस कथन की जाँच करता है।
\n\nइस लेख में, हम समझेंगे कि प्रॉपर्टी-आधारित परीक्षण कैसे काम करता है, यह सामान्य टेस्ट से कैसे अलग है, और शानदार लाइब्रेरी fast-check का उपयोग करके इसे अपने प्रोजेक्ट में कैसे शामिल करें। आप देखेंगे कि "सीमा रेखा" वाले बग्स को ढूंढना कितना आसान है, जिन्हें आपने खोजने के बारे में सोचा भी नहीं होगा।
सामान्य यूनिट टेस्ट हमेशा क्यों नहीं बचाते?
\n\nचलिए सीधे मुद्दे पर आते हैं। मान लीजिए, आपके पास एक फंक्शन है जो संख्याओं की एक सरणी को आरोही क्रम में क्रमबद्ध करता है:
\n\nfunction sortNumbers(arr) {\n return arr.slice().sort((a, b) => a - b);\n}\n\nआप एक यूनिट टेस्ट लिखते हैं:
\n\ntest('सरणी [3, 1, 2] को क्रमबद्ध करता है', () => {\n expect(sortNumbers([3, 1, 2])).toEqual([1, 2, 3]);\n});\n\nटेस्ट हरा है। आप खुश हैं। लेकिन क्या होगा अगर सरणी में null हो? या undefined? या बहुत बड़ी संख्याएँ? या 10000 तत्वों वाली सरणी? आप इनमें से प्रत्येक मामले के लिए टेस्ट नहीं लिखेंगे। लेकिन JavaScript में प्रॉपर्टी-आधारित परीक्षण लिखेगा।
उदाहरणों को सूचीबद्ध करने के बजाय, आप इनवेरिएंट (गुण) बताते हैं जो हमेशा सत्य होने चाहिए:
\n- \n
- क्रमबद्ध सरणी की लंबाई मूल सरणी की लंबाई के बराबर होती है। \n
- मूल सरणी का प्रत्येक तत्व क्रमबद्ध सरणी में मौजूद होता है। \n
- किसी भी इंडेक्स
iके लिए, यह सत्य है किarr[i] <= arr[i+1]। \n
ये वही गुण हैं जिनकी जाँच गुणों का परीक्षण करेगा।
\n\nfast-check लाइब्रेरी: रैंडम परीक्षण में आपका सहायक
\n\nJavaScript की दुनिया में, प्रॉपर्टी-आधारित परीक्षण के लिए मुख्य उपकरण fast-check है। यह किसी भी प्रकार का यादृच्छिक डेटा उत्पन्न कर सकता है: संख्याएँ, स्ट्रिंग्स, सरणियाँ, ऑब्जेक्ट्स, तिथियाँ - और यहाँ तक कि जटिल संरचनाएँ भी।
\n\nइंस्टॉलेशन सरल है:
\nnpm install fast-check --save-dev\n\nअब हम sortNumbers फंक्शन के लिए अपना पहला प्रॉपर्टी-आधारित टेस्ट लिखते हैं। हम Jest फ्रेमवर्क का उपयोग करेंगे, लेकिन fast-check किसी भी टेस्ट रनर के साथ काम करता है।
const fc = require('fast-check');\n\ntest('क्रमबद्ध करने पर सरणी की लंबाई बनी रहती है', () => {\n fc.assert(\n fc.property(fc.array(fc.integer()), (arr) => {\n const sorted = sortNumbers(arr);\n return sorted.length === arr.length;\n })\n );\n});\n\nयहाँ क्या हो रहा है? fc.array(fc.integer()) एक जनरेटर है जो यादृच्छिक पूर्णांकों की यादृच्छिक सरणियाँ बनाता है। fc.property इस जनरेटर को लेता है और डिफ़ॉल्ट रूप से 100 अलग-अलग डेटा सेट पर कथन (हमारा एरो फंक्शन) की जाँच करता है। यदि कम से कम एक टेस्ट फेल होता है - fc.assert एक एरर फेंकेगा और काउंटर-उदाहरण दिखाएगा।
और अधिक गुण जोड़ना
\n\nएक गुण अच्छा है, लेकिन तीन बेहतर हैं। आइए जाँचें कि क्रमबद्ध करने के बाद सरणी वास्तव में क्रमबद्ध है:
\n\ntest('क्रमबद्ध करने पर क्रमबद्ध सरणी लौटाता है', () =>