TypeScript में प्रॉपर्टी-आधारित परीक्षण: उन बग्स को पकड़ना जिन्हें आपने खोजा भी नहीं

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

परिचय: यूनिट-टेस्ट हर चीज़ से क्यों नहीं बचाते

\n\n

कल्पना करें कि आपने एक ऐरे सॉर्टिंग फंक्शन लिखा है। आपने इसे दस यूनिट-टेस्ट से कवर किया: खाली ऐरे, एक एलिमेंट, पहले से सॉर्ट की गई सूची, उल्टा क्रम। टेस्ट हरे हैं। आप कोड को लेकर आश्वस्त हैं। लेकिन एक हफ्ते बाद प्रोडक्शन क्रैश हो जाता है — डुप्लिकेट और नकारात्मक संख्याओं वाले 1000 एलिमेंट के ऐरे पर। परिचित लगता है?

\n\n

उदाहरणों के आधार पर पारंपरिक TypeScript परीक्षण (example-based testing) केवल उन परिदृश्यों की जाँच करता है जो आपने सोचे हैं। क्या होगा यदि बग उस संयोजन में छिपा हो जिसके बारे में आपने नहीं सोचा? यहाँ पर प्रॉपर्टी-आधारित परीक्षण (property-based testing) आता है — एक दृष्टिकोण जो स्वचालित रूप से हजारों यादृच्छिक इनपुट डेटा उत्पन्न करता है और आपके कोड के इनवेरिएंट की जाँच करता है।

\n\n

इस लेख में, हम समझेंगे कि कैसे TypeScript में प्रॉपर्टी-आधारित परीक्षण को fast-check लाइब्रेरी के साथ लागू किया जाए, किन गुणों की जाँच करनी चाहिए और यह विकास के दृष्टिकोण को कैसे बदलता है।

\n\n

प्रॉपर्टी-आधारित परीक्षण क्या है?

\n\n

यह लिखने के बजाय:

\n
it('सॉर्ट करता है [3, 1, 2] → [1, 2, 3]', () => {\n  expect(sort([3, 1, 2])).toEqual([1, 2, 3]);\n});\n
\n\n

आप एक गुण (property) का वर्णन करते हैं — एक अभिकथन जो सभी सही इनपुट डेटा के लिए सत्य होना चाहिए:

\n
it('सॉर्ट किया गया ऐरे एलिमेंट के क्रम को नहीं बदलता', () => {\n  fc.assert(\n    fc.property(fc.array(fc.integer()), (arr) => {\n      const sorted = sort(arr);\n      // गुण 1: लंबाई संरक्षित रहती है\n      expect(sorted.length).toBe(arr.length);\n      // गुण 2: मूल ऐरे का प्रत्येक एलिमेंट मौजूद है\n      // गुण 3: ऐरे आरोही क्रम में सॉर्ट किया गया है\n      for (let i = 1; i < sorted.length; i++) {\n        expect(sorted[i - 1]).toBeLessThanOrEqual(sorted[i]);\n      }\n    })\n  );\n});\n
\n\n

fast-check लाइब्रेरी स्वयं सैकड़ों यादृच्छिक ऐरे उत्पन्न करेगी (खाली, NaN वाले, दशमलव संख्याओं वाले, बड़े मानों वाले) और प्रत्येक पर आपका टेस्ट चलाएगी। यदि कोई भी विफल होता है — तो आपको समस्या के बारे में पता चल जाएगा।

\n\n

TypeScript में इसकी आवश्यकता क्यों है?

\n\n

TypeScript स्थैतिक टाइपिंग प्रदान करता है, लेकिन यह तर्क की शुद्धता की गारंटी नहीं देता। TypeScript का प्रॉपर्टी-आधारित परीक्षण "टाइप्स मैच होते हैं" और "कोड सही ढंग से काम करता है" के बीच की खाई को पाटता है। यह विशेष रूप से उपयोगी है:

\n\n
    \n
  • डेटा ट्रांसफॉर्मेशन फंक्शन (map, filter, reduce) के लिए
  • \n
  • पार्सर और वैलिडेटर के लिए
  • \n
  • गैर-तुच्छ तर्क वाले एल्गोरिदम के लिए
  • \n
  • सीमा मानों के साथ काम करने वाले फंक्शन के लिए
  • \n
\n\n

fast-check लाइब्रेरी: त्वरित शुरुआत

\n\n

प्रोजेक्ट में fast-check इंस्टॉल करें:

\n
npm install --save-dev fast-check\n
\n\n

मूल सिंटैक्स:

\n
import fc from 'fast-check';\n\ndescribe('reverse फंक्शन के गुण', () => {\n  it('reverse(reverse(arr)) === arr', () => {\n    fc.assert(\n      fc.property(fc.array(fc.anything()), (arr) => {\n        expect(reverse(reverse(arr))).toEqual(arr);\n      })\n    );\n  });\n});\n
\n\n

यहाँ fc.array(fc.anything()) — मनमाने ऐरे का जनरेटर है। आप जनरेटर को जोड़ सकते हैं:

\n
    \n
  • fc.integer() — पूर्णांक
  • \n
  • fc.string() — स्ट्रिंग्स
  • \n
  • fc.record({ name: fc.string(), age: fc.integer({ min: 0, max: 120 }) }) — ऑब्जेक्ट
  • \n
  • fc.oneof(...) — कई जनरेटर से यादृच्छिक चयन
  • \n
\n\n

किन गुणों की जाँच करें? 5 व्यावहारिक उदाहरण

\n\n

1. इनवेरिएंस (प्रतिवर्तीता)

\n

कोई भी ऑपरेशन जिसका उल्टा है, प्रतिवर्ती होना चाहिए:

\n
it('JSON का सीरियलाइज़ेशन और डीसीरियलाइज़ेशन', () => {\n  fc.assert(\n    fc.property(fc.object(), (obj) => {\n      const json = JSON.stringify(obj);\n      const parsed = JSON.parse(json);\n      expect(parsed).toEqual(obj);\n    })\n  );\n});\n<                

ब्लॉग

पुस्तक अनुशंसाएँ