单元测试(unit testing) 是指对软件 中的 最小可测试单元进行检查和验证
Go语言自身提供了一套轻量级的单元测试和性能测试系统,符合规则的测试代码会在运行测试时被自动识别执行
看看一个基本的测试案例是怎么写的
文件结构如下
| |_main.go |_utils |___func1.go |___func1_test.go |___sham_test.gofunc1.go
package utils func AddTwoNums(x, y int) (sum int) { sum = x + y return } func AddUp(x int) int { if x < 2 { return x } sum := 0 for i := 0; i <= x; i++ { sum += i } return sum }main.go
package main import ( "utils" "fmt" ) func main(){ // 调用函数AddtwoNums sum := utils.AddTwoNums(9,8) fmt.Println(sum) // 17 // 调用函数AddUp sum1 := utils.AddUp(100) fmt.Println(sum1) // 5050 }接下来我们看看测试用例怎么写
func1_test.go
package utils import ( "testing" // 导入testing包 ) // AddTwoNums的测试用例1 // 测试AddTwoNums函数 结果正确 func TestAddTwoNums1(t *testing.T) { sum := AddTwoNums(9,8) if sum != 17{ t.Error("AddTwoNums is failed",sum) } } // AddTwoNums的测试用例2 // 测试AddTwoNums函数 结果错误 func TestAddTwoNums2(t *testing.T) { sum := AddTwoNums(100,100) if sum != 2000{ t.Error("AddTwoNums is failed",sum) } } // AddUp的测试用例 // 测试AddUp函数 func TestAddUp(t *testing.T) { sum := AddUp(100) if sum != 5050{ t.Error("AddUp is failed",sum) } }sham_test.go
package utils import "testing" func TestFunc1(t *testing.T) { t.Log("TestFunc1 run") } func TestFunc2(t *testing.T) { info := "TestFunc12 run" t.Log(info + "===test log the method name `Log`") t.Logf("output : %s", info+"===test log the method name `Logf`") t.Error(info + "===test log the method name `Error`") t.Errorf("output : %s", info+"===test log the method name `Errorf`") t.Fatal(info + "===test log the method name `Fatal`") t.Fatalf("output : %s", info+"===test log the method name `Fatalf`") }我们启动单元测试
使用的命令是 go test
PS:要查看这个命令这么使用 ,可以查看帮助文档 在命令行中执行 go help testflag
执行该目录下的所有测试用例
-v 显示详细的流程
go test -v
=== RUN TestAddTwoNums1 --- PASS: TestAddTwoNums1 (0.00s) === RUN TestAddTwoNums2 --- FAIL: TestAddTwoNums2 (0.00s) func1_test.go:20: AddTwoNums is failed 200 === RUN TestAddUp --- PASS: TestAddUp (0.00s) === RUN TestFunc1 --- PASS: TestFunc1 (0.00s) sham_test.go:6: TestFunc1 run === RUN TestFunc2 --- PASS: TestFunc2 (0.00s) sham_test.go:9: TestFunc12 run FAIL exit status 1 FAIL GoNote/chapter10/demo3/utils 0.386s执行指定的单元测试用例
-run 运行需要单独执行的测试用例
go test -v -run TestAddUp
=== RUN TestAddUp --- PASS: TestAddUp (0.00s) PASS ok GoNote/chapter10/demo3/utils 0.392s执行测试文件中的所有测试用例
go test -v sham.go
=== RUN TestFunc1 --- PASS: TestFunc1 (0.00s) sham_test.go:6: TestFunc1 run === RUN TestFunc2 --- FAIL: TestFunc2 (0.00s) sham_test.go:10: TestFunc12 run===test log the method name `Log` sham_test.go:11: output : TestFunc12 run===test log the method name `Logf` sham_test.go:12: TestFunc12 run===test log the method name `Error` sham_test.go:13: output : TestFunc12 run===test log the method name `Errorf` sham_test.go:14: TestFunc12 run===test log the method name `Fatal` FAIL FAIL command-line-arguments 0.383s通过上面的例子,总结如下
测试用例文件名必须以 _test 结尾测试用例函数名必须以 Test开头测试用例函数的形参必须是 *testing.T 类型单个测试文件中可以有多个测试用例可以使用多个测试用例测试同一个内容测试用例函数不需要放在 main 函数也能执行PASS 表示测试用例运行成功 , FAIL 表示测试用例运行失败单元测试框架提供的日志方法
方法名含义Log打印日志Logf格式化打印日志Error打印错误日志, 将测试函数标记为失败,但是继续运行Errorf格式化打印错误日志 ,将测试函数标记为失败,但是继续运行Fatal打印致命错误日志,将测试函数标记为失败并停止执行Fatalf格式化打印致命错误日志,将测试函数标记为失败并停止执行PS : 在执行测试文件的时候可能会出现类似下面的情况
$ go test func1_test.go # command-line-arguments [command-line-arguments.test] .\func1_test.go:10:9: undefined: AddTwoNums .\func1_test.go:19:9: undefined: AddTwoNums .\func1_test.go:28:9: undefined: AddUp FAIL command-line-arguments [build failed]我们测试的两个函数 AddTwoNums 和 AddUp 提示未定义, 最后提示 命令行参数处理 构建失败
如何解决呢?
执行测试命令带上原文件即可
$ go test -v func1_test.go func1.go === RUN TestAddTwoNums1 --- PASS: TestAddTwoNums1 (0.00s) === RUN TestAddTwoNums2 --- FAIL: TestAddTwoNums2 (0.00s) func1_test.go:21: AddTwoNums is failed 200 === RUN TestAddUp --- PASS: TestAddUp (0.00s) FAIL FAIL command-line-arguments 0.336s基准测可以测试一段程序的运行性能及耗费CPU的程度
写法上和测试用例的类似
package utils import ( "fmt" "testing" ) // 基准测试 demo func BenchmarkDemo1(b *testing.B) { var n int // b.N 是测试框架提供 for i := 0; i < b.N; i++ { n++ } } func BenchmarkDemo2(b *testing.B) { } // 基准测试 测试函数AddTwoNums func BenchmarkAddTwoNums(b *testing.B) { for i := 0; i < b.N; i++ { sum := AddTwoNums(i, i) fmt.Sprintf("%d",sum) } }执行测试文件
$ go test -v -bench=. -benchmem -benchtime=10s bm_test.go func1.go goos: windows goarch: amd64 BenchmarkDemo1-4 10000000000 0.28 ns/op 0 B/op 0 allocs/op BenchmarkDemo2-4 10000000000 0.00 ns/op 0 B/op 0 allocs/op BenchmarkAddTwoNums-4 100000000 112 ns/op 20 B/op 2 allocs/op PASS ok command-line-arguments 14.575s命令说明
-bench=. 参数表示运行 bm_test.go 文件中所有的基准测试 ,如果想单独运行某个基准测试带上对应的名称即可,例如 -bench=BenchmarkAddTwoNums
-benchmem 参数表示显示内存分配情况
-benchtime= 参数表示自定义测试时间
测试结果说明
-4 表示4个CPU线程执行
ns/op 表示每一个操作消耗多少时间,单位是 纳秒ns
B/op 表示每一次操作需要分配的字节数
allocs/op 表示每次执行分配了多少次
