golang工具:一.测试(单元测试,基准测试)


在开发过程中,为了尽早发现代码中的缺陷和不住,我们经常要写单元测试。从而更快速的发现问题并解决问题,单元测试的效率也比传统手测更高很多。golang的单元测试很简单,先看一个例子

单元测试

用来检测一些程序逻辑的正确性。

简单示例

待测函数
package common

func Add(a,b int) int {
	return a + b
}
测试函数
package common

import "testing"

func TestAdd(t *testing.T) {
	var (
		a      = 1
		b      = 5
		expect = 6
	)

	reality := Add(a, b)
	if reality != expect {
		t.Errorf("DestroyList error: expect %v,but got %v", expect, reality)
	}
}
运行测试命令

go test -v -run TestAdd ( 这里也可以用:go test -v . 运行该包下所有的测试函数, -run 的参数实际上是一个正则表达式。-v 是显示测试命令的名称和执行时间。)

待测函数是一个加法运算,测试函数分别输入两个值然后把运行的结果和预期比对,如果和预期不符,说明我们的待测函数可能有问题,这是输出Errorf。这样就可以测试我们的待测函数。我们还可以用多组数据来测试。

多组数据

我们可以用一个数组来加入多组测试数据

package common

import "testing"

func TestAdd(t *testing.T) {
	params := [4]struct{
		A int
		B int
		Expect int
	}{
		{A:1,B: 5,Expect: 6},
		{A:0,B: 5,Expect: 5},
		{A:-2,B: 0,Expect: -2},
		{A:10,B: -10,Expect: 0},
	}

	for _,v := range params{
		reality := Add(v.A, v.B)
		if reality != v.Expect {
			t.Errorf("DestroyList error: expect %v,but got %v", v.Expect, reality)
		}
	}
}

基准测试

用来测试某些操作的性能。

简单示例

还是对上次的Add()函数进行基准测试:

func BenchmarkAdd(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Add(19,17)
	}
}
运行测试命令

go test -bench=BenchmarkAdd (-bench :选项运行基准测试,实际上它还有一个功能就是和 -run 一样可以跟一个正则表达式,另外还可以在后面加选项:-benchmem来显示内存分配统计数据: go test -bench=BenchmarkAdd -benchmem)

测试函数后面的16表示GOMAXPROCS。一共运行1000000000次,平均耗时0.215 ns/op,消耗内存0 B/op,内存分配次数0 allocs/op。待测函数没有分配额为的内存,我们再看一个例子:

用基准测试引导优化

待测函数
package common

// 获取map[string]int的值
func GetMapValue(a map[string]int) []int {
	var b []int
	for _,v := range a {
		b = append(b,v)
	}
	return b
}
测试函数
package common

import "testing"


func BenchmarkGetMapValue(b *testing.B) {
	a := map[string]int{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9,"j":0}
	
	// 重置了测试时间
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		GetMapValue(a)
	}
}

测试结果

总共测试5163984次,平均每次耗时243 ns/op,消耗内存248 B/op,分配内存次数:5 allocs/op

更改待测函数
package common

func GetMapValue(a map[string]int) []int {
	b := make([]int,0,len(a))
	for _,v := range a {
		b = append(b,v)
	}
	return b
}
再次测试

这次程序运行时间减少了近一半,内存减少了近70%, 分配次数减少了80%。