单元测试很重要.
规范
Go 语言推荐测试文件和源文件放在一起, 这一点和 Java 不一样, Java 使用 Maven 构建时, 测试文件放在单独的 test/java 目录中, 源文件放在单独的 main/java 目录中.
Go 语言中测试文件使用 _test.go
结尾. 例如当前包中有个 calc.go
的源文件, 测试文件则为 calc_test.go
.
example/
|-- calc.go
|-- calc_test.go
假设 calc.go 的代码如下:
package main
func Add(a int, b int) int {
return a + b
}
测试文件可以这么写
package main
import "testing"
func TestAdd(t *testing.T) {
if ans := Add(1, 2); ans != 3 {
t.Errorf("1 + 2 expected be 3, but %d got", ans)
}
}
- 测试方法名称一般规则是
Test
加上待测试的方法名. - 测试用的参数有且只有一个,
t *testing.T
- 基准测试(benchmark) 的参数是
b *testing.B
, TestMain 的参数是m *testing.M
.
运行
执行 go test
, 改 package 下的所有测试用例都会被执行.
$ go test
PASS
ok github.com/chengchaos/other_train/go_test/example 28.356s
执行 go test -v
, 会显示每个用例的测试结果, 另外 -cover
参数可以查看覆盖率.
$ go test -v
=== RUN TestAdd
--- PASS: TestAdd (0.00s)
PASS
ok github.com/chengchaos/other_train/go_test/example 22.017s
如果只想运行其中的一个用例, 例如 TestAdd
可以用 -run
参数指定, 该参数支持通配符 *
和部分正则表达式, 例如 ^
, $
.
$ go test -run TestAdd
PASS
ok github.com/chengchaos/other_train/go_test/example 21.727s
子测试 (Subtests)
子测试是 Go 语言内置支持的, 可以在某个测试用例中, 根据测试场景使用 t.Run
创建不同的子测试用例, 例如.
// calc_test.go
func TestMul(t *testing.T) {
t.Run("pos", func(t *testing.T) {
if Mul(2, 3) != 6 {
t.Fatal("fail")
}
})
t.Run("neg", func(t *tesging.T) {
if Mul(2, -3) != -6 {
t.Fatal("fail")
}
})
}
前面的例子, 测试失败时使用 t.Error/t.Errorf
, 这里使用了 t.Fatal/t.Fatalf
, 区别在于前者遇错不停, 还会执行其他的测试用例, 后者遇错即停.
运行子测试:
go test -run TestMul/pos -v
还没有抄完, 待续.
参考(照抄)
If you like TeXt, don’t forget to give me a star.