go工具箱test

test文件

在包目录内,所有以_test.go为后缀名的源文件在执行go build时不会被构建成包的一部分。

*_test.go文件中,有三种类型的函数:测试函数、基准测试(benchmark)函数、示例函数。go test命令会遍历所有的*_test.go文件中符合上述命名规则的函数,生成一个临时的main包用于调用相应的测试函数,接着构建并运行、报告测试结果,最后清理测试中生成的临时文件。

测试函数

测试函数是以Test为函数名前缀的函数,用于测试程序的一些逻辑行为是否正确;go test命令会调用这些测试函数并报告测试结果是PASS或FAIL。

测试函数的名字必须以Test开头,可选的后缀名必须以大写字母开头:

func TestSin(t *testing.T) { /* ... */ }

其中t参数用于报告测试失败和附加的日志信息。

举例

新建文件main_test.go:

package word

import "testing"

func IsPalindrome(s string) bool {
	for i := range s {
		if s[i] != s[len(s)-1-i] {
			return false
		}
	}
	return true
}

func TestPalindrome(t *testing.T) {
	if !IsPalindrome("kayak") {
		t.Error(`IsPalindrome("kayak") = false`)
	}
}
func TestNonPalindrome(t *testing.T) {
	if IsPalindrome("abc") {
		t.Error(`IsPalindrome("abc") = true`)
	}
}
命令行输入:go test
输出:
PASS
ok      packageStudy/test   0.053s

-v可用于打印每个测试函数的名字和运行时间。命令行输入:go test -v
输出:
=== RUN   TestPalindrome
--- PASS: TestPalindrome (0.00s)
=== RUN   TestNonPalindrome
--- PASS: TestNonPalindrome (0.00s)
PASS
ok      packageStudy/test   0.053s

-run对应一个正则表达式,名称匹配的测试函数才会被go test测试命令运行:go test -v -run "Pa"
输出:
=== RUN   TestNonPalindrome
--- PASS: TestNonPalindrome (0.00s)
PASS
ok      packageStudy/gopsutil   0.051s

 基准测试

基准测试函数是以Benchmark为函数名前缀的函数,它们用于衡量一些函数的性能;go test命令会多次运行基准函数以计算一个平均的执行时间。

基准测试是测量一个程序在固定工作负载下的性能。在Go语言中,基准测试函数和普通测试函数写法类似,但是以Benchmark为前缀名,并且带有一个*testing.B类型的参数;*testing.B参数除了提供和*testing.T类似的方法,还有额外一些和性能测量相关的方法。它还提供了一个整数N,用于指定操作执行的循环次数。

下面是IsPalindrome函数的基准测试,其中循环将执行N次。

func BenchmarkIsPalindrome(b *testing.B) {
    for i := 0; i < b.N; i++ {
        IsPalindrome("A man, a plan, a canal: Panama")
    }
}
命令行输入:go test -bench=.
//增加显示内存分配情况可用-benchmem:go test -bench=. -benchmem
输出:
goos: windows
goarch: amd64
pkg: packageStudy/test
BenchmarkIsPalindrome-4         300000000                4.22 ns/op
PASS
ok      packageStudy/gopsutil   1.766s

和普通测试不同的是,默认情况下不运行任何基准测试。通过-bench命令行标志参数指定要运行的基准测试函数。该参数是一个正则表达式,默认值是空的。其中“.”模式将可以匹配所有基准测试函数,此处也可-bench=IsPalindrome

结果中基准测试名的数字后缀部分,这里是4,表示运行时对应的GOMAXPROCS的值,这对于一些与并发相关的基准测试是重要的信息。报告显示每次调用IsPalindrome函数花费4.22纳秒,是执行300000000次的平均时间。执行次数根据每次执行时间而自动调整。

现在我们有了一个基准测试和普通测试,我们可以很容易测试改进程序运行速度的想法。也许最明显的优化是在IsPalindrome函数中第二个循环的停止检查,这样可以避免每个比较都做两次:

性能剖析

只需要开启下面其中一个标志参数就可以生成各种分析文件。当同时使用多个标志参数时需要当心,因为一项分析操作可能会影响其他项的分析结果。 

$ go test -cpuprofile=cpu.out  //CPU剖析数据标识了最耗CPU时间的函数
$ go test -blockprofile=block.out  //阻塞剖析则记录阻塞goroutine最久的操作,例如系统调用、管道发送和接收,还有获取锁等。
$ go test -memprofile=mem.out  //堆剖析则标识了最耗内存的语句。

示例函数

示例函数是以Example为函数名前缀的函数,提供一个由编译器保证正确性的示例文档。示例函数没有函数参数和返回值。

示例函数主要作用是作为文档:示例函数和注释并不一样,示例函数是真实的Go代码,需要接受编译器的编译时检查。

根据示例函数的后缀名部分,godoc这个web文档服务器会将示例函数关联到某个具体函数或包本身,因此ExampleIsPalindrome示例函数将是IsPalindrome函数文档的一部分,Example示例函数将是包文档的一部分。

go test执行测试的时候也会运行示例函数测试。如果示例函数内含有类似上面例子中的// Output:格式的注释,那么测试工具会执行这个示例函数,然后检查示例函数的标准输出与注释是否匹配。格式如下:

func ExampleIsPalindrome() {
    fmt.Println(IsPalindrome("A man, a plan, a canal: Panama"))
    fmt.Println(IsPalindrome("palindrome"))
    // Output:
    // true
    // false
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值