1. यूनिट टेस्टिंग का परिचय

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

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

2. testing पैकेज का उपयोग करके मूल टेस्ट्स करना

Go भाषा की मानक पुस्तकालय में testing पैकेज शामिल है, जो टेस्ट्स लिखने और चलाने के लिए उपकरण और कार्यक्षमता प्रदान करता है।

2.1 अपना पहला टेस्ट केस बनाना

टेस्ट फ़ंक्शन लिखने के लिए, आपको _test.go संकेत वाला फ़ाइल बनाने की आवश्यकता है। उदाहरण के लिए, यदि आपकी स्रोत कोड फ़ाइल का नाम calculator.go है, तो आपकी टेस्ट फ़ाइल का नाम calculator_test.go होना चाहिए।

अगली बारी, टेस्ट फ़ंक्शन बनाने का है। एक टेस्ट फ़ंक्शन को testing पैकेज को आयात करना होता है और निश्चित प्रारूप का पालन करना होता है। यहां एक सरल उदाहरण है:

// calculator_test.go
package calculator

import (
	"testing"
	"fmt"
)

// जोड़ने के फ़ंक्शन का टेस्ट
func TestAdd(t *testing.T) {
	result := Add(1, 2)
	expected := 3

if result != expected {
		t.Errorf("अपेक्षित %v, लेकिन प्राप्त %v", expected, result)
	}
}

इस उदाहरण में, TestAdd एक ऐसा टेस्ट फ़ंक्शन है जो एक काल्पनिक Add फ़ंक्शन का टेस्ट करता है। यदि Add फ़ंक्शन का परिणाम अपेक्षित परिणाम से मेल खाता है, तो टेस्ट सफल हो जाएगा; अन्यथा, t.Errorf को बुलाया जाएगा जिससे टेस्ट विफलता के बारे में जानकारी दर्ज की जाए।

2.2 टेस्ट फ़ंक्शनों के नामकरण नियम और हस्ताक्षर को समझना

टेस्ट फ़ंक्शनों का नाम Test से शुरू होना चाहिए, उसके बाद किसी भी छोटे अक्षरों वाली स्ट्रिंग के साथ और उनका एकमात्र पैरामीटर testing.T को इंडेर प्वॉइंटर होना चाहिए। उदाहरण के रूप में, TestAdd नामकरण नियम और हस्ताक्षर का सही पालन करता है।

2.3 टेस्ट केस चलाना

आप अपने टेस्ट केस को कमांड लाइन टूल का उपयोग करके चला सकते हैं। किसी विशिष्ट टेस्ट केस के लिए, निम्नलिखित कमांड को चलाएं:

go test -v // वर्तमान निर्देशिका में टेस्ट चलाएं और विस्तृत आउटपुट प्रदर्शित करें

यदि आप किसी विशिष्ट टेस्ट केस को चलाना चाहते हैं, तो आप -run फ़्लैग का उपयोग कर सकते हैं जिसके बाद एक सामान्य अभिव्यक्ति आती है:

go test -v -run TestAdd // केवल TestAdd टेस्ट फ़ंक्शन चलाएं

go test कमांड स्वचालित रूप से सभी _test.go फ़ाइलों को खोजेगा और मानकों को पूरा करने वाले हर टेस्ट फ़ंक्शन को निष्पादित करेगा। यदि सभी टेस्ट सफल होते हैं, तो आपको कमांड लाइन में PASS जैसा संदेश दिखाई देगा; यदि कोई भी टेस्ट विफल होता है, तो आपको FAIL के साथ संबंधित त्रुटि संदेश दिखाई देगा।

3. टेस्ट केस लिखना

3.1 t.Errorf और t.Fatalf का उपयोग करके त्रुटियाँ रिपोर्ट करना

Go भाषा में, टेस्टिंग परिवर्तन कई प्रकार की त्रुटियाँ रिपोर्ट करने के लिए उपकरण प्रदान करता है। सबसे अधिक प्रयोग होने वाले दो फ़ंक्शन Errorf और Fatalf होते हैं, दोनों ही testing.T ऑब्ज

3.2 उपटेस्ट्स को संगठित करना और उपटेस्ट्स को चलाना

Go में, हम t.Run का उपयोग करके उपटेस्ट्स को संगठित कर सकते हैं, जो हमें एक अधिक संरचित तरीके से टेस्ट कोड लिखने में मदद करता है। उपटेस्ट्स के लिए अपना Setup और Teardown हो सकता है और इन्हें व्यक्तिगत रूप से चलाया जा सकता है, जो महान लुचिपुर्वकता प्रदान करता है। यह विशेष रूप से जटिल टेस्ट या पैरामीटराइज्ड टेस्ट करने के लिए उपयोगी है।

उपटेस्ट t.Run का उपयोग करने का उदाहरण:

func TestMultiply(t *testing.T) {
    testcases := []struct {
        name           string
        a, b, expected int
    }{
        {"2x3", 2, 3, 6},
        {"-1x-1", -1, -1, 1},
        {"0x4", 0, 4, 0},
    }

    for _, tc := range testcases {
        t.Run(tc.name, func(t *testing.T) {
            if got := Multiply(tc.a, tc.b); got != tc.expected {
                t.Errorf("Multiply(%d, %d) = %d; want %d", tc.a, tc.b, got, tc.expected)
            }
        })
    }
}

अगर हम "2x3" नामक उपटेस्ट को व्यक्तिगत रूप से चलाना चाहते हैं, तो हम कमांड लाइन में निम्नलिखित कमांड चला सकते हैं:

go test -run TestMultiply/2x3

कृपया ध्यान दें कि उपटेस्ट नाम मामूली मामलों को संवेदनशील हैं।

4. परीक्षण से पहले और बाद का बहना

4.1 सेटअप और टीयरडाउन

जब हम परीक्षण करते हैं, तो हमें अक्सर परीक्षण के लिए कुछ मौलिक स्थिति तैयार करनी पड़ती है (जैसे डेटाबेस कनेक्शन, फ़ाइल निर्माण आदि), और उसी तरह, हमें परीक्षण पूरा होने के बाद कुछ सफाई कार्य करना होता है। Go में, हम आम तौर पर परीक्षण कार्यों में निर्देशिका सीधे Setup और Teardown करते हैं, और t.Cleanup कार्य हमें सफाई कॉलबैक कार्यों को पंजीकृत करने की क्षमता प्रदान करता है।

यहां एक सरल उदाहरण है:

func TestDatabase(t *testing.T) {
    db, err := SetupDatabase()
    if err != nil {
        t.Fatalf("स्थापना विफल: %v", err)
    }

    // सुनिश्चित करने के लिए कि परीक्षण पूरा होने पर डेटाबेस कनेक्शन बंद हो जाए, सफाई कॉलबैक रजिस्टर करें
    t.Cleanup(func() {
        if err := db.Close(); err != nil {
            t.Errorf("डेटाबेस बंद करने में विफल: %v", err)
        }
    })

    // परीक्षण करें...
}

TestDatabase कार्य में, हम पहले SetupDatabase कार्य को कॉल करके परीक्षण वातावरण की स्थापना करते हैं। फिर, हम t.Cleanup() का उपयोग करके पंजीकृत करते हैं जो परीक्षण पूरा होने पर सफाई कार्य करने के लिए कॉल होगा, इस उदाहरण में, यह डेटाबेस कनेक्शन बंद करना है। इस तरह, हम सुनिश्चित कर सकते हैं कि संसाधन सही तरीके से मुक्त हो जाते हैं चाहे परीक्षण सफल हो या असफल हो।

5. परीक्षण की कुशलता में सुधार

परीक्षण की कुशलता में सुधार करना हमें विकास को शीघ्रता देने, जल्दी से मुद्दों को खोजने और कोड गुणवत्ता सुनिश्चित करने में मदद कर सकता है। नीचे, हम परीक्षण कवरेज, टेबल-ड्राइवन परीक्षण, और मॉक्स के उपयोग का उपयोग करके परीक्षण की कुशलता में सुधार करेंगे।

5.1 परीक्षण कवरेज और संबंधित उपकरण

go test टूल एक बहुत उपयोगी परीक्षण कवरेज सुविधा प्रदान करता है, जो हमें समझने में मदद करता है कि कौन से कोड के हिस्से पर परीक्षण केस से ढंके जा रहे हैं, और इस तरह से परीक्षण केस से ढंके नहीं जा रहे कोड के क्षेत्रों को खोजने में मदद करती है।

go test -cover कमांड का उपयोग करके, आप सक्रिय परीक्षण कवरेज प्रतिशत देख सकते हैं:

go test -cover

अगर आपको यह समझना है कि कौन से कोड की लाइनें निष्पादित की गई थीं और कौन नहीं, तो आप आवरण डेटा फ़ाइल जेनरेट करने वाले -coverprofile पैरामीटर का उपयोग कर सकते हैं। फिर, आप go tool cover कमांड का उपयोग करके एक विस्तृत परीक्षण कवरेज रिपोर्ट जेनरेट कर सकते हैं।

go test -coverprofile=coverage.out
go tool cover -html=coverage.out

उपर्युक्त कमांड एक वेब रिपोर्ट खोलेगा, जो विजुअलीकरण करेगा कि कौन सी कोड की लाइनें परीक्षण से ढंकी गई हैं और कौन नहीं। हरा परीक्षण से ढंकी जाने वाली कोड को दर्शाएगा, जबकि लाल रंग से ओपन नहीं हुई लाइनें दिखाएंगी।

5.2 मॉक का उपयोग

परीक्षण में, हम अक्सर वहाँ संदर्भों का अनुकरण करने की आवश्यकता होती है जहां हमें बाह्य निर्भरताओं का अनुकरण करने की आवश्यकता होती है। मॉक हमें इन निर्भरताओं का अनुकरण करने में सहायक होते हैं, जिससे परीक्षण वातावरण में विशिष्ट बाह्य सेवाओं या संसाधनों पर निर्भरता को खत्म किया जा सकता है।

गो समुदाय में कई मॉक टूल्स हैं, जैसे कि testify/mock और gomock। इन उपकरणों द्वारा आम तौर पर मॉक ऑब्ज