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

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

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

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

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

\n\n

क्या आपने कभी यूनिट टेस्ट लिखे, उन्हें चलाया, सब हरा (पास) था, और फिर एप्लिकेशन उपयोगकर्ता के पहले ही गैर-मानक इनपुट पर क्रैश हो गया? परिचित लगता है। क्लासिकल टेस्ट ऐसे हैं जैसे यह जाँचना कि ताला काम करता है या नहीं, केवल अपनी चाबी डालकर। क्या होगा अगर कोई हमलावर (या सिर्फ एक संयोग) पेचकस, पेपर क्लिप या तार का टुकड़ा ले आए?

\n\n

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

\n\n

प्रॉपर्टी-आधारित परीक्षण क्या है और यह सामान्य परीक्षण से कैसे अलग है?

\n\n

कल्पना करें कि आप एक सॉर्टिंग फंक्शन का परीक्षण कर रहे हैं। एक सामान्य यूनिट टेस्ट इस तरह दिखता है:

\n\n
fn test_sort() {\n    let mut arr = vec![3, 1, 2];\n    arr.sort();\n    assert_eq!(arr, vec![1, 2, 3]);\n}
\n\n

काम करता है? काम करता है। लेकिन क्या होगा अगर ऐरे पहले से सॉर्टेड है? क्या होगा अगर वह खाली है? क्या होगा अगर उसमें 10,000 एलिमेंट उल्टे क्रम में हों? प्रत्येक मामले के लिए मैन्युअल रूप से टेस्ट लिखना अनंतता का मार्ग है।

\n\n

प्रॉपर्टी-आधारित परीक्षण दृष्टिकोण को उलट देता है। विशिष्ट इनपुट डेटा निर्दिष्ट करने के बजाय, आप एक गुण (property) का वर्णन करते हैं जो किसी भी सही इनपुट के लिए सत्य होना चाहिए। और एक विशेष लाइब्रेरी (जैसे, proptest या quickcheck) स्वयं सैकड़ों और हजारों यादृच्छिक परीक्षण मामले उत्पन्न करती है, यह खोजने की कोशिश करती है कि एकमात्र ऐसा मामला जो आपके गुण का उल्लंघन करेगा।

\n\n

सॉर्टिंग के लिए, गुण इस प्रकार हो सकता है: "सॉर्टिंग के परिणाम की लंबाई हमेशा मूल ऐरे के समान होती है, और मूल ऐरे का प्रत्येक एलिमेंट परिणाम में ठीक एक बार मौजूद होता है।" या सरल शब्दों में: "परिणाम आरोही क्रम में सॉर्ट किया गया है।"

\n\n

Rust प्रॉपर्टी-आधारित परीक्षण के लिए एक आदर्श वातावरण क्यों है

\n\n

Rust पहले से ही कंपाइलेशन चरण में कई त्रुटियों को पकड़ लेता है (मेमोरी ओनरशिप, डेटा रेस)। लेकिन बगों का एक वर्ग है जिसे कंपाइलर नहीं देखता: तार्किक त्रुटियाँ, सीमांत मामलों की गलत हैंडलिंग, विशिष्ट डेटा संयोजनों पर अप्रत्याशित व्यवहार। यहीं पर Rust प्रॉपर्टी-आधारित परीक्षण काम आता है।

\n\n

यह टाइप सिस्टम को पूरी तरह से पूरक करता है: टाइप्स गारंटी देते हैं कि डेटा की संरचना सही है, और प्रॉपर्टी-आधारित टेस्ट गारंटी देते हैं कि संभावित मानों के पूरे स्पेस के लिए इस डेटा को प्रोसेस करने का तर्क सही है।

\n\n

उपकरण: proptest बनाम quickcheck

\n\n

Rust इकोसिस्टम में दो मुख्य फ्रेमवर्क हैं: proptest और quickcheck। दोनों एक ही काम करते हैं, लेकिन अलग-अलग दर्शन के साथ।

\n\n
    \n
  • quickcheck — पुराना, न्यूनतम है। यह Arbitrary ट्रेट के माध्यम से काम करता है। आप एक फंक्शन लिखते हैं जो यादृच्छिक डेटा लेता है, और टेस्ट कई बार चलता है।
  • \n
  • proptest — आधुनिक, शक्तिशाली, डेटा जनरेशन के लिए ढेर सारी रणनीतियों के साथ। यह ठीक से कॉन्फ़िगर करने की अनुमति देता है कि कौन सा डेटा उत्पन्न करना है, और असफल उदाहरण को न्यूनतम पुनरुत्पादित मामले तक "संकीर्ण" (shrink) कर सकता है। यह आज का स्वर्ण मानक है।
  • \n
\n\n

हम proptest का उपयोग करेंगे, क्योंकि यह अधिक नियंत्रण देता है और बेहतर दस्तावेज है। इसे इंस्टॉल करें:

\n\n
# Cargo.toml\n[dev-dependencies]\nproptest = "1.4"
\n\n

Rust पर पहला प्रॉपर्टी-आधारित टेस्ट लिखना

\n\n

आइए अपनी सॉर्टिंग पर वापस आते हैं। एक टेस्ट लिखें जो जाँचता है कि परिणाम वास्तव में सॉर्ट किया गया है:

\n\n
use proptest::prelude::*;\n\nfn is_sorted<T: Ord>(slice: &[T]) -> bool {\n    slice.windows(2).all(|w| w[0] <= w[1])\n}\n\nproptest!                

ब्लॉग

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