赞
踩
关于go test的一些说明
- common_test.go文件内容如下 一个加法函数一个乘法函数
- package mytest
- import "testing"
// Add 加法
func Add(a int, b int) int {
return a + b
}
// Mul 乘法
func Mul(a int, b int) int {
return a * b
}
// 测试加法函数功能是否正常 正数
func TestAddPositive(t *testing.T) {
if ans := Add(1, 2); ans != 3 {
t.Fatalf("1 + 2 expected be 3, but %d got", ans)
}
t.Log("TestAddPositive run Success")
}
// 测试加法函数功能是否正常 负数
func TestAddNegative(t *testing.T) {
if ans := Add(-10, -20); ans != -30 {
t.Fatalf("-10 + -20 expected be -30, but %d got", ans)
}
t.Log("TestAddNegative run Success")
}
// 测试乘法函数功能是否正常
func TestMul(t *testing.T) {
if ans := Mul(3, 4); ans != 12 {
t.Fatalf("3*4 expected be 12, but %d got", ans)
}
t.Log("TestMul run Success")
}
- 命令 顺序测试文件中的所有函数
- go test -v common_test.go
- 假设mytest目录下有多个xx_test.go文件 想指定common_test.go文件中的所有函数
- 输出
- === RUN TestAddPositive
common_test.go:20: TestAddPositive run Success
--- PASS: TestAddPositive (0.00s)
=== RUN TestAddNegative
common_test.go:28: TestAddNegative run Success
--- PASS: TestAddNegative (0.00s)
=== RUN TestMul
common_test.go:36: TestMul run Success
--- PASS: TestMul (0.00s)
PASS
ok command-line-arguments 0.309s
- 命令
- go test -v -run TestAddPositive
go test -run=TestAddPositive -v
- 指定只测试目录下的TestAddPositive函数
- 输出
- === RUN TestAddPositive
common_test.go:20: TestAddPositive run Success
--- PASS: TestAddPositive (0.00s)
PASS
ok mytest 0.307s
- 命令
- go test -run=^TestAdd -v
- 可以使用正则表达式 指定一类函数,比如想测试所有TestAdd开头的函数
- 输出 会按照顺序测试目录下所有TestAdd打头的函数
- === RUN TestAddPositive
common_test.go:20: TestAddPositive run Success
--- PASS: TestAddPositive (0.00s)
=== RUN TestAddNegative
common_test.go:28: TestAddNegative run Success
--- PASS: TestAddNegative (0.00s)
PASS
ok mytest 0.359s
- forRangeBenchMark_test.go样例代码如下
- package mytest
import "testing"
// ************ benchmark range loop ************
type Person struct {
name [4096]byte
age int
}
var (
AllPerson [1024]Person
)
// BenchmarkForIndexVisit AllPerson[i].xxx 使用下标方式访问
func BenchmarkForIndexVisit(b *testing.B) {
for i := 0; i < b.N; i++ {
var age int
for i := 0; i < len(AllPerson); i++ {
age = AllPerson[i].age
}
_ = age
}
}
// BenchmarkRangeLoopVisit range循环的方式访问
func BenchmarkRangeLoopVisit(b *testing.B) {
for i := 0; i < b.N; i++ {
var age int
for _, person := range AllPerson {
age = person.age
}
_ = age
}
}
- 命令
- go test -bench=. -benchmem forRangeBenchMark_test.go
- 输出
- goos: darwin
goarch: amd64
cpu: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz
BenchmarkForIndexVisit-6 4570186 246.8 ns/op 0 B/op 0 allocs/op
BenchmarkRangeLoopVisit-6 4777 228750 ns/op 0 B/op 0 allocs/op
PASS
ok command-line-arguments 2.858s- 这里可以看出直接for range的方式遍历性能很差 因为for range会有一个临时变量复制的过程,这个过程比较消耗时间
- 命令
- go test -bench=BenchmarkRangeLoopVisit -benchmem
- 输出
- goos: darwin
goarch: amd64
pkg: mytest
cpu: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz
BenchmarkRangeLoopVisit-6 4657 345054 ns/op 0 B/op 0 allocs/op
PASS
ok mytest 1.950s
- 命令
- go test -bench=^BenchmarkRange -benchmem
- 所有以BenchmarkRange打头的都会测试
- 命令
- go test -bench=. -benchmem forRangeBenchMark_test.go -benchtime=5s
- 默认1s 下面指定运行时间为5s
- 输出
- goos: darwin
goarch: amd64
cpu: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz
BenchmarkForIndexVisit-6 24010926 248.3 ns/op 0 B/op 0 allocs/op
BenchmarkRangeLoopVisit-6 24183 242653 ns/op 0 B/op 0 allocs/op
PASS
ok command-line-arguments 14.918s
- BenchmarkForIndexVisit函数在5s内运行了24010926次 每次大概耗时 248.3 ns
- BenchmarkRangeLoopVisit函数在5s内运行了24183次 每次大概耗时 242653 ns 性能相当差
- 命令
- go test -bench=. -benchmem forRangeBenchMark_test.go -benchtime=10000x
- 输出
- goos: darwin
goarch: amd64
cpu: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz
BenchmarkForIndexVisit-6 10000 246.6 ns/op 0 B/op 0 allocs/op
BenchmarkRangeLoopVisit-6 10000 300624 ns/op 0 B/op 0 allocs/op
PASS
ok command-line-arguments 3.347s
- 测试过程也可以看到BenchmarkRangeLoopVisit运行耗时很长,而BenchmarkForIndexVisit很快就结束了
- 每次函数调用前后需要一些准备工作和清理工作,我们可以使用 StopTimer 暂停计时以及使用 StartTimer 开始计时
- func Benchmarkxxx(b *testing.B) {
for n := 0; n < b.N; n++ {
b.StopTimer()
// 准备数据
b.StartTimer()
Sort(nums)
}
}
func Benchmarkxxx(b *testing.B) {
//准备工作部分代码
b.ResetTimer() // 重置定时器
for n := 0; n < b.N; n++ {
fib(30) // run fib(30) b.N times
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。