go
单元测试与性能优化
go
单元测试与性能优化
这篇博客简单总结go
的单元测试和性能优化相关的知识。
1. 单元测试
Go语言中的测试依赖go test
命令。编写测试代码和编写普通的Go代码过程是类似的。编写完代码后只需在命令行执行相应命令即可运行测试代码。
go test -v
显示详细信息。
go test -cover
查看测试覆盖率
go test -cover -coverprofile=xx.out
将测试覆盖率输出到xx.out
文件
go tool cover -html=xx.out
使用浏览器分析文件
在包目录中以 _test.go
为后缀的源代码属于测试代码。不会被go build
编译到可执行文件中。测试代码中主要由三种类型的函数:测试函数、性能基准函数、示例函数。
测试代码方便测试,写完..._test.go
文件后,修改源代码后直接执行go test
命令即可!!!go test
命令会遍历所有的*_test.go
文件中符合上述命名规则的函数,然后生成一个临时的main包用于调用相应的测试函数,然后构建并运行、报告测试结果,最后清理测试中生成的临时文件。
1. 测试函数
// 如在 add_test.go 文件里 // 格式必须是这样! Test... func TestAdd1(t *testing.T){ // ... } func TestAdd2(t *testing.T){ // ... } func Test...(t *testing.T){ // ... }
类似的测试逻辑写多个测试函数过于臃肿,可以用测试组,就是放在一个函数里。
func TestAdd(t *testing.T){ // 利用结构体存储多组测试用例 type testCase struct{ // 待测试的函数参数 ... // 期望结果 want []int } // 初始化一个结构体切片 testGroup := []testCase{ testCase{...}, testCase{...}, testCase{...}, } // 遍历切片,调用函数得到结果与want进行比较。 }
这样想看一下某一个特定测试用例的结果就比较麻烦,于是又引出子测试:就是把结构体切片换成map
。这样还可以单独的只测试某一个测试用例:
go test -run=TestAdd/case1
func TestAdd(t *testing.T){ // 利用结构体存储多组测试用例 type testCase struct{ // 待测试的函数参数 ... // 期望结果 want []int } // 初始化一个map testGroup := map[string]testCase{ "case1": testCase{...}, "case1": testCase{...}, "case1": testCase{...}, } // 遍历map,调用函数得到结果与want进行比较。 }
2. 性能基准函数
go test -bench=Add
执行基准函数
go test -bench=Add -cpu=1
执行基准函数,只使用一个CPU,默认是跑满所有。
go test -bench=Add -benchmem
执行基准函数同时查看内存情况
// 格式 Benchmark... func BenchmarkAdd(b testing.B){ // 必须执行 b.N 遍待测试函数 for i := 0; i < b.N; i++{ // 执行待测试函数 } }
Setup
与 Teardown
: 执行测试之前的准备工作和测试之后的恢复工作。
3. 示例函数
比较少用。
// 格式 func ExampleAdd(){ // ... }
2. 性能优化pprof
性能测试 pprof
,记录快照信息。
需要测试性能时才开启pprof
,不需要的时候就关掉,因为测试性能本身会占用很多资源。
性能优化指标:==CPU
使用情况、内存使用、==死锁情况....
1. CPU
性能分析
// 开始CPU检测 pprof.StartCPUProfile(w io.Writer) // 停止检测 pprof.StopCPUProfile()
2. 内存分析
pprof.WriteHeapProfile(w io.Writer)
3. 相关命令
go tool pprof xxx.pprof
分析生成的文件,进入交互模式
而后 top
查看哪些进程占用CPU
,占用时间是多少(就和Linux
的top
命令类似);list 进程名
查看进程内具体哪一行代码占用CPU
时间最长。
以上就是这篇博客的简单内容,后面继续对所学的内容进行简单归纳整理!加油。
1. 单元测试
go test
命令
go test -v
显示详细信息。
go test -cover
查看测试覆盖率
go test -cover -coverprofile=xx.out
将测试覆盖率输出到xx.out
文件
go tool cover -html=xx.out
使用浏览器分析文件
在包目录中以 _test.go
为后缀的源代码属于测试代码。不会被go build
编译到可执行文件中。测试代码中主要由三种类型的函数:测试函数、性能基准函数、示例函数。
测试代码方便测试,写完..._test.go
文件后,修改源代码后直接执行go test
命令即可!!!
1. 测试函数
// 如在 add_test.go 文件里 // 格式必须是这样! Test... func TestAdd1(t *testing.T){ // ... } func TestAdd2(t *testing.T){ // ... } func Test...(t *testing.T){ // ... }
类似的测试逻辑写多个测试函数过于臃肿,可以用测试组,就是放在一个函数里。
func TestAdd(t *testing.T){ // 利用结构体存储多组测试用例 type testCase struct{ // 待测试的函数参数 ... // 期望结果 want []int } // 初始化一个结构体切片 testGroup := []testCase{ testCase{...}, testCase{...}, testCase{...}, } // 遍历切片,调用函数得到结果与want进行比较。 }
这样想看一下某一个特定测试用例的结果就比较麻烦,于是又引出子测试:就是把结构体切片换成map
。这样还可以单独的只测试某一个测试用例:
go test -run=TestAdd/case1
func TestAdd(t *testing.T){ // 利用结构体存储多组测试用例 type testCase struct{ // 待测试的函数参数 ... // 期望结果 want []int } // 初始化一个map testGroup := map[string]testCase{ "case1": testCase{...}, "case1": testCase{...}, "case1": testCase{...}, } // 遍历map,调用函数得到结果与want进行比较。 }
2. 性能基准函数
go test -bench=Add
执行基准函数
go test -bench=Add -cpu=1
执行基准函数,只使用一个CPU,默认是跑满所有。
go test -bench=Add -benchmem
执行基准函数同时查看内存情况
// 格式 Benchmark... func BenchmarkAdd(b testing.B){ // 必须执行 b.N 遍待测试函数 for i := 0; i < b.N; i++{ // 执行待测试函数 } }
Setup
与 Teardown
: 执行测试之前的准备工作和测试之后的恢复工作。
3. 示例函数
比较少用。
// 格式 func ExampleAdd(){ // ... }
2. 性能优化pprof
性能测试 pprof
,记录快照信息。
需要测试性能时才开启pprof
,不需要的时候就关掉,因为测试性能本身会占用很多资源。
性能优化指标:==CPU
使用情况、内存使用、==死锁情况....
1. CPU
性能分析
// 开始CPU检测 pprof.StartCPUProfile(w io.Writer) // 停止检测 pprof.StopCPUProfile()
2. 内存分析
pprof.WriteHeapProfile(w io.Writer)
3. 相关命令
go tool pprof xxx.pprof
分析生成的文件,进入交互模式
而后 top
查看哪些进程占用CPU
,占用时间是多少(就和Linux
的top
命令类似);list 进程名
查看进程内具体哪一行代码占用CPU
时间最长。
以上就是这篇博客的简单内容,后面继续对所学的内容进行简单归纳整理!加油。