golang学习记录(13)
go中的单元测试
1、单元测试用例
go test命令是一个按照一定约定和组织的测试代码驱动程序
在包目录中,所有以_test.go结尾的源码文件都会被go test运行到
我们写的 _test.go源码文件不用担心内容过多,因为go test命令不会将这些测试文件打包到最后的可执行文件
在实际应用中,test文件有四类:
1、Test开头的:功能测试
2、Benchmark开头的:性能测试
3、Example开头的:模糊测试
4、TestMain开头的:单元测试
1.1、单元测试用例编写
下面举一个单元测试的例子:
在包目录中有三个go文件,分别是:
1、add.go
2、add_test.go
3、main.go
在add.go中定义了一个Add函数,用来实现两个整数的相加:
在add_test.go中首先导入”testing”包,然后定义了一个TestAdd函数,用来测试Add函数的正确性,并作出相应的出错处理:
1
2
3
4
5
6
7
8
import "testing"
func TestAdd(t *testing.T){
re := add(1,2)
if re!= 3{
t.Errorf("add(1,2) = %d; want 3", re)
}
}
之后对add_test.go文件执行go test命令,即可进行单元测试,查看测试结果
1.2、跳过耗时的单元测试用例
在实际应用中,我们可能会遇到一些耗时的单元测试用例,我们可以使用t.Skip()函数来跳过这些耗时的单元测试用例
在执行测试文件的过程中,使用 go test -short命令可以查看测试结果,其中 -short命令会跳过所有耗时的单元测试用例
耗时的单元测试用例是有自己定义的
下面是一个使用跳过单元测试的例子:
1
2
3
4
5
6
7
8
9
10
func TestAdd(t *testing.T){
if testing.Short(){
t.Skip("skip this test")
}
// 下面是执行不到的
re := add(1,2)
if re!= 3{
t.Errorf("add(1,2) = %d; want 3", re)
}
}
testing中的short相当于采用了两种模式,供用户选择。
2、基于表格驱动测试
在实际测试的的时候,测试用例可能不止一组,一个一个测试非常耗时,go中提供了一种基于表格驱动测试的方式,它可以一次性测试多组数据,提高测试效率
下面是一个基于表格驱动测试的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import "testing"
func TestAdd(t *testing.T){
var tests = []struct{
a int
b int
want int
}{
{1,2,3},
{2,3,5},
{3,4,7},
}
for _, tt := range tests{
re := add(tt.a, tt.b)
if re!= tt.want{
t.Errorf("add(%d, %d) = %d; want %d", tt.a, tt.b, re, tt.want)
}
}
}
3、benchmark性能测试
在一些核心函数中对性能有要求,我们可以使用benchmark性能测试来测试函数的性能
同样,性能测试函数也在”testing”包中
在应用过程中,性能测试函数的命名必须以Benchmark开头,后面跟上要测试的函数名
性能测试函数的参数必须是*testing.B类型的指针
在执行测试文件的过程中,使用 go test -bench命令可以查看测试结果,其中 -bench命令会执行所有的性能测试用例
下面是一个关于单元性能测试的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import "testing"
func BenchmarkAdd(b *testing.B){
a := 123
b := 456
c := 579
for i:=0; i<b.N; i++{
if actual := add(a,b); actual!= c{
fmt.Printf("add(%d, %d) = %d; want %d", a, b, actual, c)
}
}
在进行性能测试过沉重还有一个常用的函数:b.ResetTimer(),它可以重置计时器,使得测试结果更加准确