Go单元测试
Go单元测试概要
Go 语言的单元测试默认采用官方自带的测试框架,通过引入 testing 包以及 执行 go test 命令来实现单元测试功能。
在源代码包目录内,所有以 _test.go 为后缀名的源文件会被 go test 认定为单元测试的文件,这些单元测试的文件不会包含在 go build 的源代码构建中,而是单独通过 go test 来编译并执行。
Go单元测试基本规范
Go 单元测试的基本规范如下:
- 每个测试函数都必须导入 testing 包。测试函数的命名类似
func TestName(t *testing.T),入参必须是*testing.T - 测试函数的函数名必须以大写的 Test 开头,后面紧跟的函数名,要么是大写开关,要么就是下划线,比如
func TestName(t *testing.T)或者func Test_name(t *testing.T)都是 ok 的, 但是func Testname(t *testing.T)不会被检测到 - 通常情况下,需要将测试文件和源代码放在同一个包内。一般测试文件的命名,都是
{source_filename}_test.go,比如我们的源代码文件是allen.go,那么就会在allen.go的相同目录下,再建立一个allen_test.go的单元测试文件去测试allen.go文件里的相关方法。
当运行 go test 命令时,go test 会遍历所有的 *_test.go 中符合上述命名规则的函数,然后生成一个临时的 main 包用于调用相应的测试函数,然后构建并运行、报告测试结果,最后清理测试中生成的临时文件。
从一个简单测试用例来确认 go test 的各种使用方法
一个简单的xxx_test.go的单元测试文件如下,里面有两个测试方法:
package util
import (
"testing"
)
func TestSum(t *testing.T) {
if Sum(1, 2, 3) != 6 {
t.Fatal("sum error")
}
}
func TestAbs(t *testing.T) {
if Abs(5) != 5 {
t.Fatal("abs error, except:5, result:", Abs(5))
}
}
go test -v 执行单测并打印详情
运行方法:进入到包内,运行命令 go test -v ,参数 -v 可以打印详情。 也可以只运行某个方法的单元测试: go test -v -run="xxx" ,支持正则表达式。
allen@MackBook:~/work/goDev/Applications/src/baseCodeExample/gotest$go test -v
=== RUN TestSum
--- PASS: TestSum (0.00s)
=== RUN TestAbs
--- PASS: TestAbs (0.00s)
PASS
ok baseCodeExample/gotest 0.005s
allen@MackBook:~/work/goDev/Applications/src/baseCodeExample/gotest$go test -v -run="Abs"
=== RUN TestAbs
--- PASS: TestAbs (0.00s)
PASS
ok baseCodeExample/gotest 0.006s
go test -v -cover 执行单测并计算覆盖率
go test 工具还有个功能是测试单元测试的覆盖率,用法为 go test -v -cover, 示例如下:
allen@MackBook:~/work/goDev/Applications/src/baseCodeExample/gotest$go test -v -cover
=== RUN TestSum
--- PASS: TestSum (0.00s)
=== RUN TestAbs
--- PASS: TestAbs (0.00s)
PASS
coverage: 85.7% of statements
ok baseCodeExample/gotest 0.005s
从覆盖率来看(coverage: 85.7% of statements),单元测试没有覆盖全部的代码,只有 85.7% ,我们可以通过如下命令将 cover 的详细信息保存到cover.out 中。
go test -cover -coverprofile=cover.out -covermode=count
注:
-cover 允许代码分析
-covermode 代码分析模式(set:是否执行;count:执行次数;atomic:次数,并发执行)
-coverprofile 输出结果文件
然后再通过
go tool cover -func=cover.out
查看每个方法的覆盖率。
allen@MackBook:~/work/goDev/Applications/src/baseCodeExample/gotest$go tool cover -func=cover.out
baseCodeExample/gotest/compute.go:5: Sum 100.0%
baseCodeExample/gotest/compute.go:13: Abs 66.7%
total: (statements) 85.7%
这里发现是 Abs 方法没有覆盖完全,因为我们的用例只用到了正数的那个分支。 还可以使用 html 的方式查看具体的覆盖情况。
go tool cover -html=cover.out
Go 单测覆盖度的相关命令汇总如下:
go test -v -cover
go test -cover -coverprofile=cover.out -covermode=count
go tool cover -func=cover.out