Go unit test 13

Brief introduction: unit test, Go test
What is recorded here is my unskilled grammar and knowledge
Details step by step: Li Wenzhou's blog (very detailed)
https://www.liwenzhou.com/posts/Go/16_test/#autoid-0-0-0
(there was no function test at that time, so I copied it. Hey, hey, hey)
#Test function
In a SPList The function to be tested is written in the go file. The file name can be arbitrary, but it is generally the same as the file name for "value correspondence";
In a In the go file, if there are multiple functions that need to be tested, you need... What file is generally required_ test what file
In Golan IDE, you can hold down the Ctrl key and point to the tested function and press it to display relevant contents

//Split string
// Split cuts s according to spe and returns the slice of a string
// Split("I love you", "love") = > ["I", "you"]
func Split(s, sep string) (ret []string) {
	ret = make([]string, 0, strings.Count(s, sep)+1)
	idx := strings.Index(s, sep)
	for idx > -1 {
		ret = append(ret, s[:idx]) // The append() function will request memory when the capacity is insufficient
		s = s[idx+len(sep):]
		idx = strings.Index(s, sep)
	}
	ret = append(ret, s)
	return
}

In this way, the tested function is defined

#Test case
Create split in folder_ test. Go test files can also be created in other folders, but the package should be imported.
The first letter of the Test function must be uppercase Test + the name of the function under Test
**You also need to receive a * testing T type parameter

func TestSplit(t *testing.T) {
	//Got: = split ("I love you", "love")
	//Want: = [] string {"I", "you"}
	//Slices cannot be compared directly. channel and map are the same
	got := Split("a:b:c", ":")
	want := []string{"a", "b", "c"}
	if !reflect.DeepEqual(got, want) { //DeepEqual is used to compare "incomparable" and "comparison of reference types"
		t.Errorf("want:%v got:%v", want, got)
	}
}

go test

Of course, it's too hasty to test just one example
The map type can cover as many situations of input and output as possible.

func TestSplit(t *testing.T) {
	type test struct {
		input string
		sep   string
		want  []string
	}
	tests := map[string]test{
		"simple":  {input: "a:b:c", sep: ":", want: []string{"a", "b", "c"}},
		"chinese": {input: "silly-force", sep: "-", want: []string{"silly", "force"}},
	}

	for name, tc := range tests {
		got := Split(tc.input, tc.sep)
		if !reflect.DeepEqual(got, tc.want) {
			t.Errorf("name %v failed, want:%v got:%v ", name, tc.want, got)
		}
	}
}

Of course, you may need to check the specific situation of a specific test case during testing
To see the specific situation of a function - Test. Go() V

func TestSplit(t *testing.T) {
	type test struct {
		input string
		sep   string
		want  []string
	}
	tests := map[string]test{
		"simple":  {input: "a:b:c", sep: ":", want: []string{"a", "b", "c"}},
		"chinese": {input: "silly-force", sep: "-", want: []string{"silly", "force"}},
	}
	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			got := Split(tc.input, tc.sep)
			if !reflect.DeepEqual(got, tc.want) {
				t.Errorf("name %v failed, want:%v got:%v ", name, tc.want, got)
			}
		})
	}
}

In addition, you can test the specified use cases separately
go test -run=Split/chinese run a test case separately (not demonstrated)
chinese here refers to "chinese" in the map type
The effect is the same as testing a function alone

#Reset time

func BenchmarkSplit(b *testing.B) {
	time.Sleep(5 * time.Second) // Suppose you need to do some time-consuming irrelevant operations
	b.ResetTimer()              // Reset timer
	for i := 0; i < b.N; i++ {
		Split("Sand river has sand and river", "sand")
	}
}

#View coverage
In my own opinion, this is the most (Dior) thing.
go test -cover
You can also see which codes are overwritten
go test -coverprofile=c.out
Visual output of coverage to c.out (random file name. Random file suffix)
go tool cover -html=c.out
If you open the c.out file in html, you can't drag the file directly to the browser. You must use the above command.

#Performance benchmark
Principle: call very, very many times to see the function: average execution time, memory application consumption, and so on (??).

func BenchmarkSplit(b *testing.B) {
	// b.N is not a fixed number, but at least run enough for 1 second
	for i := 0; i < b.N; i++ {
		Split("Front, middle and rear", "in")
	}
}

go test -bench=Split

Data interpretation
BenchmarkSplit-8 (-8 go maxprocess processes) (CPU work)
12269937 execution times
97.5 ns/op each operation takes 97.5 nanoseconds

However, we usually add * * - benchmem * * when testing to count the memory allocation.

Data interpretation
32B/op memory consumed per operation
1. Number of memory requests per allocs / op operation

#Performance comparison function

The comparison method is generally used to test the performance of functions, but the above test method is somewhat thin, so the comparison method is used in most cases.
There are many ways to deal with the same problem.
For example, we want to know how much time a function takes to process 1W and 10W times, or how much the new energy difference is when two different algorithms achieve the same effect.

(this is copied)
Function under test

func Asd(n int) int {
	i := 0
	for {
		if n == 1 {
			return i
		}
		n = n / 2
		i++
	}
}

Test function

func benchmarkFib(b *testing.B, n int) {
	for i := 0; i < b.N; i++ {
		Fib(n)
	}
}

func BenchmarkFib1(b *testing.B)  { benchmarkFib(b, 1) }
func BenchmarkFib2(b *testing.B)  { benchmarkFib(b, 2) }
func BenchmarkFib3(b *testing.B)  { benchmarkFib(b, 3) }
func BenchmarkFib10(b *testing.B) { benchmarkFib(b, 10) }
func BenchmarkFib20(b *testing.B) { benchmarkFib(b, 20) }
func BenchmarkFib40(b *testing.B) { benchmarkFib(b, 40) }

**go test -bench=.**test all
go test -bench=Fib40 -benchtime=20stest Fib40 run for 20 seconds

#Parallel testing

func BenchmarkSplitParallel(b *testing.B) {
	// b.SetParallelism(1) / / set the number of CPU s used
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			Split("Sand river has sand and river", "sand")
		}
	})
}

https://www.liwenzhou.com/posts/Go/16_test/#autoid-0-0-0
https://www.bilibili.com/video/av66788366/

Keywords: goland

Added by cerebrus189 on Tue, 08 Feb 2022 15:51:28 +0200