खोज…
परिचय
गो अपनी स्वयं की परीक्षण सुविधाओं के साथ आता है जिसमें परीक्षण और बेंचमार्क चलाने के लिए आवश्यक सभी चीजें हैं। अधिकांश अन्य प्रोग्रामिंग भाषाओं के विपरीत, अक्सर एक अलग परीक्षण ढांचे की आवश्यकता नहीं होती है, हालांकि कुछ मौजूद हैं।
बेसिक टेस्ट
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