खोज…


परिचय

गो अपनी स्वयं की परीक्षण सुविधाओं के साथ आता है जिसमें परीक्षण और बेंचमार्क चलाने के लिए आवश्यक सभी चीजें हैं। अधिकांश अन्य प्रोग्रामिंग भाषाओं के विपरीत, अक्सर एक अलग परीक्षण ढांचे की आवश्यकता नहीं होती है, हालांकि कुछ मौजूद हैं।

बेसिक टेस्ट

main.go :

package main

import (
    "fmt"
)

func main() {
    fmt.Println(Sum(4,5))
}

func Sum(a, b int) int {
    return a + b
}

main_test.go :

package main

import (
    "testing"
)

// Test methods start with `Test`
func TestSum(t *testing.T) {
    got := Sum(1, 2)
    want := 3
    if got != want {
        t.Errorf("Sum(1, 2) == %d, want %d", got, want)
    }
}

परीक्षण को चलाने के लिए सिर्फ go test कमांड का उपयोग करें:

$ go test
ok      test_app    0.005s

प्रत्येक परीक्षण के परिणाम देखने के लिए -v ध्वज का उपयोग करें:

$ go test -v
=== RUN   TestSum
--- PASS: TestSum (0.00s)
PASS
ok      _/tmp    0.000s

पथ का उपयोग करें ./... परीक्षण करने के लिए उपनिर्देशिका पुनरावर्ती:

$ go test -v ./...
ok      github.com/me/project/dir1    0.008s
=== RUN   TestSum
--- PASS: TestSum (0.00s)
PASS
ok      github.com/me/project/dir2    0.008s
=== RUN   TestDiff
--- PASS: TestDiff (0.00s)
PASS

विशेष परीक्षण चलाएं:
यदि कई परीक्षण हैं और आप एक विशिष्ट परीक्षण चलाना चाहते हैं, तो इसे इस तरह किया जा सकता है:

go test -v -run=<TestName> // will execute only test with this name

उदाहरण:

go test -v run=TestSum

बेंचमार्क परीक्षण

यदि आप मानदंड मापना चाहते हैं तो इस तरह एक परीक्षण विधि जोड़ें:

sum.go :

package sum

// Sum calculates the sum of two integers
func Sum(a, b int) int {
    return a + b
}

sum_test.go :

package sum

import "testing"

func BenchmarkSum(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = Sum(2, 3)
    }
}

फिर एक साधारण बेंचमार्क चलाने के लिए:

$ go test -bench=. 
BenchmarkSum-8    2000000000             0.49 ns/op
ok      so/sum    1.027s

तालिका संचालित इकाई परीक्षण

इस प्रकार का परीक्षण पूर्वनिर्धारित इनपुट और आउटपुट मूल्यों के साथ परीक्षण के लिए लोकप्रिय तकनीक है।

सामग्री के साथ main.go नामक एक फ़ाइल बनाएँ:

package main

import (
    "fmt"
)

func main() {
    fmt.Println(Sum(4, 5))
}

func Sum(a, b int) int {
    return a + b
}

आपके द्वारा इसे चलाने के बाद, आप देखेंगे कि आउटपुट 9 । हालांकि Sum फ़ंक्शन बहुत सरल लगता है, यह आपके कोड का परीक्षण करने के लिए एक अच्छा विचार है। ऐसा करने के लिए, हम main_test.go में एक ही फ़ोल्डर में main.go नाम की फ़ाइल main.go , जिसमें निम्न कोड होते हैं:

package main

import (
    "testing"
)

// Test methods start with Test
func TestSum(t *testing.T) {
    // Note that the data variable is of type array of anonymous struct,
    // which is very handy for writing table-driven unit tests.
    data := []struct {
        a, b, res int
    }{
        {1, 2, 3},
        {0, 0, 0},
        {1, -1, 0},
        {2, 3, 5},
        {1000, 234, 1234},
    }

    for _, d := range data {
        if got := Sum(d.a, d.b); got != d.res {
            t.Errorf("Sum(%d, %d) == %d, want %d", d.a, d.b, got, d.res)
        }
    }
}

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

उदाहरण परीक्षण (स्वयं दस्तावेज परीक्षण)

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

sum.go :

package sum

// Sum calculates the sum of two integers
func Sum(a, b int) int {
    return a + b
}

sum_test.go :

package sum

import "fmt"

func ExampleSum() {
    x := Sum(1, 2)
    fmt.Println(x)
    fmt.Println(Sum(-1, -1))
    fmt.Println(Sum(0, 0))

    // Output:
    // 3
    // -2
    // 0
}

अपने परीक्षण को निष्पादित करने के लिए, उन फ़ाइलों वाले फ़ोल्डर में go test चलाएं या उन दो फ़ाइलों को sum नाम के उप-फ़ोल्डर में डालें और फिर मूल फ़ोल्डर से go test ./sum । दोनों ही मामलों में आपको इसके समान आउटपुट मिलेगा:

ok      so/sum    0.005s

यदि आप सोच रहे हैं कि यह आपके कोड का परीक्षण कैसे कर रहा है, तो यहां एक और उदाहरण फ़ंक्शन है, जो वास्तव में परीक्षण में विफल रहता है:

func ExampleSum_fail() {
    x := Sum(1, 2)
    fmt.Println(x)

    // Output:
    // 5
}

जब आप go test चलते go test , तो आपको निम्न आउटपुट मिलते हैं:

$ go test
--- FAIL: ExampleSum_fail (0.00s)
got:
3
want:
5
FAIL
exit status 1
FAIL    so/sum    0.006s

यदि आप अपने sum पैकेज के लिए दस्तावेज देखना चाहते हैं - बस चलाएं:

go doc -http=:6060

और करने के लिए नेविगेट http: // localhost: 6060 / pkg / फ़ोल्डर / योग / , जहां फ़ोल्डर वाले फ़ोल्डर है sum (इस उदाहरण में पैकेज so )। योग विधि के लिए दस्तावेज इस तरह दिखता है:

यहाँ छवि विवरण दर्ज करें

HTTP अनुरोधों का परीक्षण

main.go:

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

func fetchContent(url string) (string, error) {
    res, err := http.Get(url)
    if err != nil {
        return "", nil
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        return "", err
    }
    return string(body), nil
}

func main() {
    url := "https://example.com/"
    content, err := fetchContent(url)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Content:", content)
}

main_test.go:

package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"
    "testing"
)

func Test_fetchContent(t *testing.T) {
    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "hello world")
    }))
    defer ts.Close()

    content, err := fetchContent(ts.URL)
    if err != nil {
        t.Error(err)
    }

    want := "hello world"
    if content != want {
        t.Errorf("Got %q, want %q", content, want)
    }
}

टेस्ट में सेट / मॉक फंक्शन को रीसेट करें

यह उदाहरण दिखाता है कि एक फ़ंक्शन कॉल को कैसे मॉक करें जो हमारी इकाई परीक्षण के लिए अप्रासंगिक है, और फिर मॉक किए गए फ़ंक्शन को अपने मूल फ़ंक्शन पर वापस कॉल defer लिए defer स्टेटमेंट का उपयोग करें।

var validate = validateDTD

// ParseXML parses b for XML elements and values, and returns them as a map of 
// string key/value pairs.
func ParseXML(b []byte) (map[string]string, error) {
    // we don't care about validating against DTD in our unit test
    if err := validate(b); err != nil {
        return err
    }

    // code to parse b etc.
}

func validateDTD(b []byte) error {
    // get the DTD from some external storage, use it to validate b etc.
}

हमारे इकाई परीक्षण में,

func TestParseXML(t *testing.T) {
    // assign the original validate function to a variable.
    originalValidate = validate
    // use the mockValidate function in this test.
    validate = mockValidate
    // defer the re-assignment back to the original validate function.
    defer func() {
       validate = originalValidate
    }()

    var input []byte
    actual, err := ParseXML(input)
    // assertion etc.
}

func mockValidate(b []byte) error {
    return nil // always return nil since we don't care
}

सेटअप और टियरडाउन फ़ंक्शन का उपयोग करके परीक्षण

आप एक सेटअप और टियरडाउन फ़ंक्शन सेट कर सकते हैं।

  • एक सेटअप फ़ंक्शन आपके वातावरण को परीक्षणों के लिए तैयार करता है।
  • एक टियरडाउन फ़ंक्शन एक रोलबैक करता है।

यह एक अच्छा विकल्प है जब आप अपने डेटाबेस को संशोधित नहीं कर सकते हैं और आपको एक ऑब्जेक्ट बनाने की आवश्यकता होती है जो डेटाबेस में लाई गई किसी वस्तु का अनुकरण करता है या प्रत्येक परीक्षण में एक कॉन्फ़िगरेशन को सम्मिलित करने की आवश्यकता होती है।

एक मूर्खतापूर्ण उदाहरण होगा:

// Standard numbers map
var numbers map[string]int = map[string]int{"zero": 0, "three": 3}

// TestMain will exec each test, one by one
func TestMain(m *testing.M) {
    // exec setUp function
    setUp("one", 1)
    // exec test and this returns an exit code to pass to os
    retCode := m.Run()
    // exec tearDown function
    tearDown("one")
    // If exit code is distinct of zero,
    // the test will be failed (red)
    os.Exit(retCode)
}

// setUp function, add a number to numbers slice
func setUp(key string, value int) {
    numbers[key] = value
}

// tearDown function, delete a number to numbers slice
func tearDown(key string) {
    delete(numbers, key)
}

// First test
func TestOnePlusOne(t *testing.T) {
    numbers["one"] = numbers["one"] + 1

    if numbers["one"] != 2 {
        t.Error("1 plus 1 = 2, not %v", value)
    }
}

// Second test
func TestOnePlusTwo(t *testing.T) {
    numbers["one"] = numbers["one"] + 2

    if numbers["one"] != 3 {
        t.Error("1 plus 2 = 3, not %v", value)
    }
}

अन्य उदाहरण डेटाबेस का परीक्षण करने और रोलबैक करने के लिए तैयार करना होगा

 // ID of Person will be saved in database
personID := 12345
// Name of Person will be saved in database
personName := "Toni"

func TestMain(m *testing.M) {
    // You create an Person and you save in database
    setUp(&Person{
            ID:   personID,
            Name: personName,
            Age:  19,
        })
    retCode := m.Run()
    // When you have executed the test, the Person is deleted from database
    tearDown(personID)
    os.Exit(retCode)
}

func setUp(P *Person) {
    // ...
    db.add(P)
    // ...
}

func tearDown(id int) {
    // ...
    db.delete(id)
    // ...
}

func getPerson(t *testing.T) {
    P := Get(personID)
    
    if P.Name != personName {
        t.Error("P.Name is %s and it must be Toni", P.Name)
    }
}

HTML प्रारूप में कोड कवरेज देखें

सामान्य go test रूप में रन go test , फिर भी coverprofile ध्वज के साथ। फिर HTML के रूप में परिणाम देखने के लिए go tool का उपयोग करें।

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


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow