प्रॉपर्टी-आधारित परीक्षण Go में: कोड लिखने से पहले ही तोड़ दें

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

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

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

जब यूनिट टेस्ट झूठ बोलते हैं और बग बने रहते हैं

\n\n

आपने 20 यूनिट टेस्ट लिखे। सभी हरे हैं। CI पास हो जाता है। आप संतुष्ट हैं। और फिर - प्रोडक्शन में एक बग। परिचित लगता है? क्लासिक परिदृश्य: आपने केवल उन्हीं मामलों का परीक्षण किया जो आपने स्वयं सोचे थे। और वास्तविकता, जैसे कि जानबूझकर, ऐसे संयोजन देती है जिनके बारे में आपने सोचा भी नहीं था।

\n\n

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

\n\n

इस लेख में, हम gopter लाइब्रेरी की मदद से Go में प्रॉपर्टी-आधारित परीक्षण को लागू करने का तरीका समझेंगे, वास्तविक उदाहरण लिखेंगे और देखेंगे कि कौन से बग पकड़े जा सकते हैं। चलिए शुरू करते हैं!

\n\n

प्रॉपर्टी-आधारित परीक्षण क्या है और इसकी आवश्यकता क्यों है?

\n\n

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

\n\n
func TestSort(t *testing.T) {\n    input := []int{3, 1, 2}\n    result := sort(input)\n    expected := []int{1, 2, 3}\n    if !reflect.DeepEqual(result, expected) {\n        t.Errorf("got %v, want %v", result, expected)\n    }\n}
\n\n

ठीक है, यह काम करता है। लेकिन क्या होगा अगर ऐरे खाली है? क्या होगा अगर सभी तत्व समान हैं? क्या होगा अगर ऋणात्मक संख्याएँ हैं? आप 10 और टेस्ट लिख सकते हैं, लेकिन फिर भी कुछ छूट जाएगा।

\n\n

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

\n\n
    \n
  • सॉर्ट किए गए ऐरे की लंबाई मूल ऐरे की लंबाई के बराबर होती है।
  • \n
  • मूल ऐरे का प्रत्येक तत्व सॉर्ट किए गए ऐरे में मौजूद होता है (और इसके विपरीत)।
  • \n
  • ऐरे आरोही क्रम में सॉर्ट किया गया है।
  • \n
\n\n

फ्रेमवर्क (उदाहरण के लिए, gopter या बिल्ट-इन testing/quick) यादृच्छिक इनपुट डेटा उत्पन्न करता है और जाँचता है कि सभी गुण पूरे होते हैं। यदि कोई बग है - तो आपको इसके बारे में पता चल जाएगा, भले ही आपको पता न हो कि कहाँ देखना है।

\n\n

प्रॉपर्टी-आधारित परीक्षण के लिए Go लाइब्रेरीज़

\n\n

Go इकोसिस्टम में कई उपकरण हैं:

\n\n
    \n
  • testing/quick - बिल्ट-इन पैकेज, न्यूनतम, लेकिन सीमित क्षमताओं के साथ।
  • \n
  • gopter - जनरेटर, श्रिंकिंग (इनपुट डेटा को छोटा करना) और लचीली सेटिंग्स के साथ एक शक्तिशाली लाइब्रेरी। हम इसी की सलाह देते हैं।
  • \n
  • rapid - एक आधुनिक विकल्प, अधिक प्रदर्शनकारी।
  • \n
\n\n

हम gopter का उपयोग करेंगे, क्योंकि इसके पास बेहतर दस्तावेज़ीकरण और समुदाय है। स्थापना:

\n\n
go get github.com/leanovate/gopter
\n\n

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

\n\n

मान लीजिए, हमारे पास एक फ़ंक्शन Reverse है जो स्ट्रिंग को उलटता है:

\n\n
func Reverse(s string) string {\n    runes := []rune(s)\n    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {\n        runes[i], runes[j] = runes[j], runes[i]\n    }\n    return string(runes)\n}
\n\n

किस गुण की जाँच की जा सकती है? यदि स्ट्रिंग को दो बार उलटा जाए, तो हमें मूल स्ट्रिंग मिलनी चाहिए:

\n\n
import (\n    "testing"\n    "github.com/leanovate/gopter"\n    "github.com/leanovate/gopter/gen"\n)\n\nfunc TestReverseTwice(t *testing.T) {\n    properties := gopter.NewProperties(nil)\n\n    properties.Property("reverse(reverse(s)) == s", prop.ForAll(\n        func(s string) bool {\n            return Reverse(Reverse(s)) == s\n        },\n        gen.AnyString(),\n    ))\n\n    properties.TestingRun(t)\n}
\n\n

टेस्ट चलाएँ - और gopter 100 यादृच्छिक स्ट्रिंग उत्पन्न करेगा, गुण की जाँच करेगा। यदि सब कुछ ठीक है - टेस्ट हरा है। यदि नहीं - तो आपको एक काउंटरएग्ज़ाम्पल (सबसे छोटी स्ट्रिंग जिस पर टेस्ट फेल हुआ) मिलेगा।

\n\n

बो

ब्लॉग

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