文章

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

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(),它可以重置计时器,使得测试结果更加准确

本文由作者按照 CC BY 4.0 进行授权