Rust में परीक्षण: गुणवत्तापूर्ण कोड के लिए फ्रेमवर्क और उपकरण

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

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

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

Rust में परीक्षण: यूनिट-टेस्ट से property-based testing तक



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



अंतर्निहित साधन: cargo test



मूल परीक्षण उपकरण सीधे कंपाइलर और पैकेज मैनेजर में बनाया गया है। परीक्षण बनाने के लिए, बस #[cfg(test)] विशेषता वाला एक मॉड्यूल जोड़ें और फ़ंक्शन को #[test] विशेषता से चिह्नित करें।



// src/lib.rspub fn add(left: u64, right: u64) -> u64 {    left + right}

#[cfg(test)]mod tests { use super::*;

#[test] fn test_add() { let result = add(2, 2); assert_eq!(result, 4); }

#[test] fn test_add_negative() { // u64 ऋणात्मक संख्याओं का समर्थन नहीं करता - यह एक संकलन त्रुटि है // लेकिन यदि फ़ंक्शन i64 स्वीकार करता: // assert_eq!(add(-2, 2), 0); }}


चलाएँ: cargo test। फ़्लैग -- --nocapture परीक्षणों से println! आउटपुट करता है। फ़्लैग -- --test-threads=1 समानांतर निष्पादन को अक्षम करता है।



एकीकरण परीक्षण



एकीकरण परीक्षण प्रोजेक्ट रूट स्तर पर tests/ फ़ोल्डर में स्थित होते हैं। प्रत्येक फ़ाइल एक अलग क्रेट है जो लाइब्रेरी के सार्वजनिक API का परीक्षण कर सकती है।



// tests/integration_test.rsuse my_library::add;

#[test]fn test_integration() { assert_eq!(add(10, 20), 30);}


बाइनरी क्रेट्स (main.rs के साथ) के परीक्षण के लिए, assert_cmd का उपयोग किया जा सकता है - यह बाइनरी को एक बाहरी प्रक्रिया के रूप में चलाता है और stdout/stderr की जाँच करता है।



Property-based testing: proptest और quickcheck



दर्जनों परीक्षण मामलों को मैन्युअल रूप से लिखने के बजाय, property-based testing हजारों यादृच्छिक इनपुट डेटा उत्पन्न करता है और इनवेरिएंट की जाँच करता है। दो मुख्य फ्रेमवर्क:



  • proptest - आधुनिक, लचीला, रणनीतियों, फ़िल्टरिंग और उदाहरण संपीड़न (shrink) के समर्थन के साथ।
  • quickcheck - पुराना, Haskell के QuickCheck से प्रेरित, सरल लेकिन कम शक्तिशाली।


proptest के साथ उदाहरण:



use proptest::prelude::*;

fn reverse_string(s: &str) -> String { s.chars().rev().collect()}

proptest! { #[test] fn test_reverse_twice(s in ".*") { let reversed = reverse_string(&s); let double_reversed = reverse_string(&reversed); assert_eq!(s, double_reversed); }

#[test] fn test_reverse_length(s in ".*") { let reversed = reverse_string(&s); assert_eq!(s.len(), reversed.len()); }}


यदि परीक्षण विफल होता है, तो proptest न्यूनतम काउंटर-उदाहरण (shrinking) ढूँढता है।



अतुल्यकालिक कोड का परीक्षण: tokio-test



tokio के साथ काम करने वाले अतुल्यकालिक फ़ंक्शन के लिए, सामान्य परीक्षण उपयुक्त नहीं हैं - एक अतुल्यकालिक रनटाइम की आवश्यकता है। tokio-test मैक्रो #[tokio::test] प्रदान करता है।



use tokio::time::{sleep, Duration};

async fn delayed_add(a: u32, b: u32) -> u32 { sleep(Duration::from_millis(10)).await; a + b}

#[tokio::test]async fn test_delayed_add() { let result = delayed_add(3, 5).await; assert_eq!(result, 8);}


futures और async-std के साथ काम करने के लिए futures-test का भी उपयोग किया जा सकता है।



मॉक और स्टब्स: mockall और mockito



बाहरी निर्भरताओं (DB, API, फ़ाइल सिस्टम) से परीक्षणों को अलग करने के लिए, मॉक और स्टब्स का उपयोग किया जाता है। mockall ट्रेट्स के लिए शक्तिशाली मॉक उत्पन्न करता है, और mockito HTTP मॉक सर्वर बनाता है।

अनुशंसाएँ