代码结构
wohu@wohu-dev:~/gocode/src$ tree demo/
demo/
├── main.go
└── main_test.go
0 directories, 2 files
wohu@wohu-dev:~/gocode/src$
main_test.go
内容:
package main
import (
"fmt"
"testing"
)
func TestPrint(t *testing.T) {
// t.SkipNow()
res := Print()
if res != 100 {
t.Errorf("Return wrong value")
}
}
func TestPrint2(t *testing.T) {
res := Print()
if res+1 != 101 {
t.Errorf("Return wrong value")
}
}
func TestSequence(t *testing.T) {
t.Run("s1", func(t *testing.T) { fmt.Println("s1") })
t.Run("s2", func(t *testing.T) { fmt.Println("s2") })
t.Run("s3", func(t *testing.T) { fmt.Println("s3") })
}
func TestMain(m *testing.M) {
fmt.Println("test main start")
// 如果没有调用 m.Run(),则除了 TestMain 之外其它的 tests 都不会被执行
m.Run()
}
func TestAll(t *testing.T) {
t.Run("TestPrint", TestPrint)
t.Run("TestPrint2", TestPrint2)
}
// 注意:使用 Benchmark 时的命令为 go test -bench=.
// 要测试的函数的运行时间必须在 b.N 运行次数是稳定的,不能是随着 i 次数的增多而增加
func BenchmarkAll(b *testing.B) {
for i := 0; i < b.N; i++ {
Print()
}
}
main.go
内容
package main
func Print() int {
return 100
}
运行结果:
wohu@wohu-dev:~/gocode/src/demo$ go test -v
test main start
=== RUN TestPrint
--- PASS: TestPrint (0.00s)
=== RUN TestPrint2
--- FAIL: TestPrint2 (0.00s)
main_test.go:21: Return wrong value
=== RUN TestSequence
=== RUN TestSequence/s1
s1
=== RUN TestSequence/s2
s2
=== RUN TestSequence/s3
s3
--- PASS: TestSequence (0.00s)
--- PASS: TestSequence/s1 (0.00s)
--- PASS: TestSequence/s2 (0.00s)
--- PASS: TestSequence/s3 (0.00s)
=== RUN TestAll
=== RUN TestAll/TestPrint
=== RUN TestAll/TestPrint2
--- FAIL: TestAll (0.00s)
--- PASS: TestAll/TestPrint (0.00s)
--- FAIL: TestAll/TestPrint2 (0.00s)
main_test.go:21: Return wrong value
FAIL
ok demo 0.006s
wohu@wohu-dev:~/gocode/src/demo$
运行结果:
wohu@wohu-dev:~/gocode/src/demo$ go test -bench=.
test main start
s1
s2
s3
goos: linux
goarch: amd64
pkg: demo
BenchmarkAll-4 1000000000 0.280 ns/op
PASS
ok demo 0.332s
wohu@wohu-dev:~/gocode/src/demo$
注意点:
- 每个
test
文件必须import
一个testing
包; test case
的入参必须为t *testing.T
或者b *testing.B
;t.SkipNow()
跳过当前test
, 并且直接按照Pass
处理继续下一个test
test
文件下的每一个test case
均必须以Test
开头,并且符合TestXXX
的形式,否则go test
会直接跳过测试不执行;Go
的test
不会保证多个TestXXX
顺序执行,但通常会按照顺序执行,我们不应该依赖这个顺序;- 使用
t.Run
来执行subtests
可以做到控制test
的输出以及test
的顺序; - 使用
TestMain
作为初始化test
, 并且使用m.Run()
来调用其它tests
可以完成一些需要初始化操作的testing
比如数据库连接、文件打开、restful
服务登录等;