一、本文概要

本文会介绍go当中进行测试过程的一些方法,

二、文件规范

以 _test.go 结尾的 go 文件会被视为测试文件,在进行 go build 编译生成可执行程序时,这些 _test.go 文件不会被编译。

三、编码规范

测试函数参数支持以下几种类型: * testing.T
该参数是我们最常用参数,被测试的方法需要以 Test 开头,如 TestAddUser、TestListUsers ,它主要用于测试程序的业务逻辑,

  func TestAddUser(t *testing.T) {

  }

可以通过 -run 指定需要测试哪些函数,可以通过 -v 输入测试过程中,各个测试函数输出的详情,如:

  go test -v -run=Add* users_test.go
  • testing.B
    该参数主要用于性能测试,它需要在测试时调用-bench参数来执行,而需要测试的函数必须以Benchmark开头 func BenchmarkAddUser(t *testing.T) { }

在运行 go test -bench 需要注意 -bench 用于指定要测试的对象,如-bench=.则表示测试所有带Benchmark的函数,完整的执行命令

  go test -bench=Add* users_test.go
  • testing.M
    每一个测试文件只能包含一个testing.M,它相当于测试文件的Main函数,它的优化级在我们要测试的函数之前, 因此可以用来装载一些需求初始化的数据,它只能按以下格式进行编码:

    func TestMain(t *testing.M) {
    // 此处加入需要初始化内容
    m.Run()
    }
    
  • testing.PB

四、执行语法

usage: go test [build/test flags] [packages] [build/test flags & test binary flags]

为了让 GO 语言的测试框架能够自动发现我们所有的测试用例,测试函数的签名也要遵循其特定的规则:

函数名必须以 Test 开头,后面通常是待测方法的函数名 参数必须是 *testing.T,它提供了 Error,Fatal 等方法用来报错和终止测试的运行

Go语言中的单元测试,分为【测试】和【基准性能测试】,【测试】就是看一个函数或方法,写的是否正确,能否得到预期的运行结果;【基准性能测试】就是指,测试一个函数或者方法的性能或效率,比如一个排序算法,排列一个包含1000万个元素的随机数组,总耗时是多少,内存开销是多少。

*_test.go文件必须放在被测试文件同级目录,否则无法被覆盖测试抓取

集成测试

单元测试

http://goconvey.co/

https://blog.csdn.net/qq_41431406/article/details/100914477

main包里定义的全局变量别的包是无法引用的。

通常选择放在global包或其他自定义的包中,然后让其他包来引用

go test -c -covermode=count -coverpkg ./...

参数

  • 参数-v可用于打印每个测试函数的名字和运行时间:

    $ go test -v
    === RUN TestPalindrome
    --- PASS: TestPalindrome (0.00s)
    === RUN TestNonPalindrome
    --- PASS: TestNonPalindrome (0.00s)
    === RUN TestFrenchPalindrome
    --- FAIL: TestFrenchPalindrome (0.00s)
    word_test.go:28: IsPalindrome("été") = false
    === RUN TestCanalPalindrome
    --- FAIL: TestCanalPalindrome (0.00s)
    word_test.go:35: IsPalindrome("A man, a plan, a canal: Panama") = false
    FAIL
    exit status 1
    FAIL    gopl.io/ch11/word1  0.017s
    
  • 参数-run对应一个正则表达式,只有测试函数名被它正确匹配的测试函数才会被go test测试命令运行:

    $ go test -v -run="French|Canal"
    === RUN TestFrenchPalindrome
    --- FAIL: TestFrenchPalindrome (0.00s)
    word_test.go:28: IsPalindrome("été") = false
    === RUN TestCanalPalindrome
    --- FAIL: TestCanalPalindrome (0.00s)
    word_test.go:35: IsPalindrome("A man, a plan, a canal: Panama") = false
    FAIL
    exit status 1
    FAIL    gopl.io/ch11/word1  0.014s
    

前言 前面的章节我们分析了每种测试的数据结构及其实现原理,本节我们看一下go test的执行机制。

Go 有多个命令行工具,go test只是其中一个。go test命令的函数入口在src\cmd\go\internal\test\test.go:runTest(),这个函数就是go test的大脑。

runTest() runTest()函数场景如下:

func runTest(cmd *base.Command, args []string) GO 命令行工具的实现中,都遵循这种函数声明,其中args即命令行输入的全部参数。

runTest首先会分析所有需要测试的包,为每个待测包生成一个二进制文件,然后执行。

两种运行模式 go test运行时,跟据是否指定package分为两种模式,即本地目录模式和包列表模式。

本地目录模式 当执行测试并没有指定package时,即以本地目录模式运行,例如使用"go test"或者"go test -v"来启动测试。 本地目录模式下,go test编译当前目录的源码文件和测试文件,并生成一个二进制文件,最后执行并打印结果。

包列表模式 当执行测试并显式指定package时,即以包列表模式运行,例如使用"go test math"来启动测试。 包列表模式下,go test为每个包生成一个测试二进制文件,并分别执行它。 包列表模式是在Go 1.10版本才引入的,它会把每个包的测试结果写入到本地临时文件中做为缓存,下次执行时会直接从缓存中读取测试结果,以便节省测试时间。

C:\Users\apple>go test gorm
can't load package: package gorm: cannot find package "gorm" in any of:
        c:\go\src\gorm (from $GOROOT)
        C:\Users\apple\go\src\gorm (from $GOPATH)

可以看到,包列表模式,先会从$GOROOT寻找包名,当$GOROOT不存在时,会向$GOPATH中去寻找

缓存机制 当满足一定的条件,测试的缓存是自动启用的,也可以显式的关闭缓存。

测试结果缓存 如果一次测试中,其参数全部来自"可缓存参数"集合,那么本次测试结果将被缓存。

可缓存参数集合如下:

-cpu
-list
-parallel
-run
-short
-v

需要注意的是,测试参数必须全部来自这个集合,其结果才会被缓存,没有参数或包含任一此集合之外的参数,结果都不会缓存。

时间周期

init -> func TestMain(m *testing.M) -> func TestFunc(t *testing.T)

http://shouce.jb51.net/gopl-zh/ch11/ch11-02.html