Go测试小结 - Go语言中文社区

Go测试小结


怎么写一个go的测试

  1. 文件命名方式是:[name]_test.go
  2. 对于测试函数命名规则:普通测试fun Test[FuncName](t *testing.T),基准测试func Benchmark[FuncName](b *testing.B)
  3. 运行测试:普通测试go test .,基准测试go test -bench .

代码示例:

func TestTriangle(t *testing.T)  {
	tests := []struct {a, b, c int} {
		{3, 4, 5},
		{5, 12, 13},
		{8, 15, 17},
		{12, 35, 37},
		{30000, 40000, 50000},
	}

	for _, tt := range tests {
		// callTriangle 求直角边函数
		if actual := callTriangle(tt.a, tt.b); actual != tt.c {
			t.Errorf("callTriangle(%d, %d);" +
				"got %d; expected %d", tt.a, tt.b, actual, tt.c)
		}
	}
}

// 基准测试
func BenchmarkTriangle(b *testing.B) {
	x, y, z := 30000, 40000, 50000
	for i:=0; i<b.N; i++ {
		if actual := callTriangle(x, y); actual != z {
			b.Errorf("callTriangle(%d, %d);" +
				"got %d; expected %d", x, y, actual, z)
		}
	}
}

表格驱动测试

在Go语言中比较推崇表格驱动测试,因为和普通的测试相比,表格驱动测试有如下优点:

  1. 测试逻辑和测试数据分开
  2. 出错信息明显
  3. 数据出错了,测试继续
  4. go语言很容易实现表格驱动测试

代码示例:上面第一个测试就是表格驱动测试

覆盖率

测试的覆盖率写到c.out上,并使用go tool输出到网页中。

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

效果:绿色表示测试覆盖到的代码
在这里插入图片描述

性能测试

通过go提供的工具来对代码进行性能上的分析。先将cpu性能分析文件输出cpu.out,再用pprof工具对cpu.out进行查看。

被测试代码

// 求最短不重复子串
func lengthOfNonRepeatingSubStr(s string) int {
	lastOccurred := make(map[rune]int)
	start := 0
	maxLength := 0

	for i, ch := range []rune(s) {
		if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
			start = lastI + 1
		}
		if i-start+1 > maxLength {
			maxLength = i - start + 1
		}
		lastOccurred[ch] = i
	}

	return maxLength
}

func BenchmarkNoeepeating(b *testing.B)  {
	s := "黑化肥挥发发灰会花飞灰化肥挥发发黑会飞花"
	for i:=0; i<13; i++ {
		s = s + s	}
	
	ans := 8
	
	
	for i:=0; i<b.N; i++ {
		if l := lengthOfNonRepeatingSubStr(s); l != ans {
			b.Errorf("got %d for input %s;" +
				"expected %d",
				l, s, ans)
		}
	}
}

终端执行代码如下:

go test -bench .  -cpuprofile cpu.out
go tool pprof cpu.out 

执行完上面的语句会进入pprof内部的命令行。
最简单的分析方式就是使用web输出成svg文件进行查看。如果该指令没有效果说明没有安装graphviz工具输入sudo apt install graphviz即可。然后再运行web就可以看到下图:
在这里插入图片描述
图中会显示函数运行过程中调用了哪些模块,每个模块在运行过程中消耗了cpu资源的占比。
通过上面的图可以查看,比如上面代码中改用slice会更快。

服务器测试

方式:

  1. 通过使用假的Request/Response
  2. 通过启动一个服务

代码示例:完整代码

var tests = []struct {
	h       appHandler
	code    int
	message string
}{
	{errPanic, 500, "Internal Server Error"},
	{errUserError, 400, "user error"},
	{errNotFound, 404, "Not Found"},
	{errNotPermission, 403, "Forbidden"},
	{errUnknown, 500, "Internal Server Error"},
	{noError, 200, "no error"},
}

func TestErrWrapper(t *testing.T) {

	for _, tt := range tests {
		f := errWrapper(tt.h)
		response := httptest.NewRecorder()
		request := httptest.NewRequest(
			http.MethodGet,
			"http://www.imooc.com", nil)

		f(response, request)

		verifyResponse(response.Result(), tt.code, tt.message, t)
	}
}

func TestErrWrapperInServer(t *testing.T) {
	for _, tt := range tests {
		f := errWrapper(tt.h)
		server := httptest.NewServer(http.HandlerFunc(f))
		resp, _ := http.Get(server.URL)
		verifyResponse(resp, tt.code, tt.message, t)
	}
}

func verifyResponse(resp *http.Response, expectedCode int,
	expectedMsg string, t * testing.T)  {

	b, _ := ioutil.ReadAll(resp.Body)
	body := strings.Trim(string(b), "n")
	if resp.StatusCode != expectedCode || body != expectedMsg {
		t.Errorf("expect (%d, %s);"+
			"got (%d, %s)",
			expectedCode, expectedMsg,
			resp.StatusCode, body)
	}
}

文档

直接是用godoc查看文档

输出测试

需要在函数末端添加注释,// Output:然后后面每一行按上面的输出顺序写好结果,运行就可以测试该函数是否和运行的结果是一样的。

func ExampleQueue_Pop() {
	q := Queue{}
	q.Push(23)
	q.Push(59)
	q.Push(5)
	fmt.Println(q.Pop())
	fmt.Println(q.Pop())
	fmt.Println(q.IsEmpty())
	fmt.Println(q.Pop())
	fmt.Println(q.IsEmpty())

	// Output:
	// 23
	// 59
	// false
	// 5
	// true
}
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_37720172/article/details/108589718
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢