关于go test的一些说明
- golang安装后可以使用go test工具进行单元测试 代码片段对比的性能测试,使用起来还是比较方便,下面是一些应用场景 - 平时自己想做一些简单函数的单元测试,不用每次都新建一个main.go 然后go run main.go- 相对某个功能做下性能测试 看下cpu/内存消耗情况
- 可以针对性的建立一些目录 存放自己的一些测试代码
- 一些使用规则- 创建代码保存目录 这里以mytest目录为例- 目录下的文件名都要以_test.go结尾 比如common_test.go- package mytest 不要为main- import testing包- 普通单元测试 函数名以Test开头- 性能测试 函数名称以Benchmark开头- 目录下面函数名不要重名
普通单元测试常见用法
样例代码
- 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("34 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)PASSok command-line-arguments 0.309s
指定测试某一个函数
- 命令
- go test -v -run TestAddPositivego test -run=TestAddPositive -v - 指定只测试目录下的TestAddPositive函数
- 输出
- === RUN TestAddPositive common_test.go:20: TestAddPositive run Success--- PASS: TestAddPositive (0.00s)PASSok 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)PASSok mytest 0.359s
测试目录下所有文件中的全部函数
- 命令 会按照顺序测试目录下所有_test.go结尾的所有函数
- go test -v .
性能测试的常见用法
样例代码
- forRangeBenchMark_test.go样例代码如下
- package mytestimport "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 }}
-benchmem会打印内存申请信息,建议都打开这个选项
指定某一个文件测试
- 命令
- go test -bench=. -benchmem forRangeBenchMark_test.go
- 输出
- goos: darwingoarch: amd64cpu: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHzBenchmarkForIndexVisit-6 4570186 246.8 ns/op 0 B/op 0 allocs/opBenchmarkRangeLoopVisit-6 4777 228750 ns/op 0 B/op 0 allocs/opPASSok command-line-arguments 2.858s
- 这里可以看出直接for range的方式遍历性能很差 因为for range会有一个临时变量复制的过程,这个过程比较消耗时间
指定某一个函数测试
- 命令
- go test -bench=BenchmarkRangeLoopVisit -benchmem
- 输出
- goos: darwingoarch: amd64pkg: mytestcpu: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHzBenchmarkRangeLoopVisit-6 4657 345054 ns/op 0 B/op 0 allocs/opPASSok mytest 1.950s
指定某一类函数
- 命令
- go test -bench=^BenchmarkRange -benchmem - 所有以BenchmarkRange打头的都会测试
指定测试时间
- 命令
- go test -bench=. -benchmem forRangeBenchMark_test.go -benchtime=5s - 默认1s 下面指定运行时间为5s
- 输出
- goos: darwingoarch: amd64cpu: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHzBenchmarkForIndexVisit-6 24010926 248.3 ns/op 0 B/op 0 allocs/opBenchmarkRangeLoopVisit-6 24183 242653 ns/op 0 B/op 0 allocs/opPASSok 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: darwingoarch: amd64cpu: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHzBenchmarkForIndexVisit-6 10000 246.6 ns/op 0 B/op 0 allocs/opBenchmarkRangeLoopVisit-6 10000 300624 ns/op 0 B/op 0 allocs/opPASSok command-line-arguments 3.347s - 测试过程也可以看到BenchmarkRangeLoopVisit运行耗时很长,而BenchmarkForIndexVisit很快就结束了
性能测试-timer相关api
ResetTimer
- 如果在 benchmark 开始前,需要一些准备工作,如果准备工作比较耗时,则需要将这部分代码的耗时忽略掉
StopTimer & StartTimer
- 每次函数调用前后需要一些准备工作和清理工作,我们可以使用 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 }}
标签:
golang
本文转载自: https://blog.csdn.net/imheketong/article/details/140502457
版权归原作者 疯子爱淡定 所有, 如有侵权,请联系我们删除。
版权归原作者 疯子爱淡定 所有, 如有侵权,请联系我们删除。