博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
独孤九剑(0x04) - 测试篇
阅读量:7048 次
发布时间:2019-06-28

本文共 4073 字,大约阅读时间需要 13 分钟。

《南皮县志·风土志下·歌谣》:“兵马不动,粮草先行”。作战时兵马还没出动,军用粮草的运输要先行一步。在开发新功能之前,先编写测试代码,然后只编写使测试通过的功能代码,这种测试驱动开发的软件开发模式是我非常推荐的。

对 Dit 的贡献要求需要通过单元测试,编写 Dit 的任意模块,都需要一并编写测试用例。本文先简述一下 Go 对测试的支持,后续会陆续提供 Dit 的测试方案和测试报告。

Go 对测试的支持

Go 自带的测试框架 支持单元测试和性能测试。Go 规定测试文件以 _test.go 为后缀,使用命令 go test 命令自动运行测试用例。

单元测试

Test 开头的方法为一个测试用例,并拥有一个参数 *testing.T, 写法如下:

func TestXxx(*testing.T)

Xxx 部分为任意的字母数字组合,首字母不能是小写字母。*testing.T 可记录错误或者标记错误状态。可通过Short判断略过一部分测试,加快测试时间。如下:

func TestTimeConsuming(t *testing.T) {  if testing.Short() {    t.Skip("skipping test in short mode.")  }  ...}

性能测试

性能测试用例以 Benchmark 开始,参数为 *testing.B, 写法如下:

func BenchmarkXxx(*testing.B)

使用 go test 运行性能测试用例时,需要加上参数 -bench

在编写性能测试用例时,需牢记在循环体内使用 testing.B.N , 以使测试可以正常的运行:

func BenchmarkHello(b *testing.B) {  for i := 0; i < b.N; i++ {    fmt.Sprintf("hello")  }}

对耗时的初始化操作,可在测试用例内部重置计时器 ResetTimer,确保引入不必要的误差:

func BenchmarkBigLen(b *testing.B) {  big := NewBig()  b.ResetTimer()  for i := 0; i < b.N; i++ {    big.Len()  }}

使用 RunParallel 测试并行模块, 运行时需要加上参数 -cpu:

func BenchmarkTemplateParallel(b *testing.B) {  templ := template.Must(template.New("test").Parse("Hello, {
{.}}!")) b.RunParallel(func(pb *testing.PB) { var buf bytes.Buffer for pb.Next() { buf.Reset() templ.Execute(&buf, "World") } })}

标准输出测试

包提供对标准终端输出的测试, 测试用例以 Example 开始,结果使用注释的方式,写在 Output: 之后:

func ExampleHello() {  fmt.Println("hello")  // Output: hello}

Example 用例的命名规则:

func Example() { ... }func ExampleF() { ... } // F - functionfunc ExampleT() { ... } // T - typefunc ExampleT_M() { ... } // T_M - method M on type T// 多个 example 可用后缀区分,The suffix must start with a lower-case letter.func Example_suffix() { ... }func ExampleF_suffix() { ... }func ExampleT_suffix() { ... }func ExampleT_M_suffix() { ... }

Main 测试

当需要批量 setup 或 teardown 测试环境时,可使用:

func TestMain(m *testing.M)

TestMain 简单实现如下:

func TestMain(m *testing.M) {  flag.Parse()  os.Exit(m.Run())}

Demo

写一个简单的示例,来 Demo 一下 testing 测试框架的用法。

// div.gopackage testimport (  "errors")func div(a, b int) (int, error) {  if b == 0 {    return 0, errors.New("b must NOT be 0")  }  return a / b, nil}// div_test.gopackage testimport (  "errors"  "flag"  "fmt"  "os"  "testing"  "time")func TestDivNormal(t *testing.T) {  ret, err := div(6, 2)  if err != nil || ret != 3 {    t.Error("6/2=3")  }}func TestDivZero(t *testing.T) {  _, err := div(6, 0)  if err.Error() != errors.New("b must NOT be 0").Error() {    t.Error("zero div error")  }}func BenchmarkDiv(b *testing.B) {  b.Log("run times:", b.N)  for i := 0; i < b.N; i++ {    div(6, 2)  }}func BenchmarkDiv_Sleep(b *testing.B) {  b.Log("run times:", b.N)  time.Sleep(3000) // 模拟费时操作  b.ResetTimer()  for i := 0; i < b.N; i++ {    div(6, 2)  }}func ExampleOutput() {  ret, _ := div(6, 2)  fmt.Println("6 / 2 =", ret)  // Output:  // 6 / 2 = 3}func TestMain(m *testing.M) {  flag.Parse()  fmt.Println("Setup ... Done")  ret := m.Run()  fmt.Println("Teardown ... Done")  os.Exit(ret)}

运行 go test -v, 结果如下:

localhost:test zdd$ go test -vSetup ... Done=== RUN TestDivNormal--- PASS: TestDivNormal (0.00s)=== RUN TestDivZero--- PASS: TestDivZero (0.00s)=== RUN: ExampleOutput--- PASS: ExampleOutput (0.00s)PASSTeardown ... Doneok    github.com/zddhub/hellogo/test  0.005s

默认不执行性能测试用例,使用go test -v -bench .执行:

localhost:test zdd$ go test -v -bench .Setup ... Done=== RUN TestDivNormal--- PASS: TestDivNormal (0.00s)=== RUN TestDivZero--- PASS: TestDivZero (0.00s)=== RUN: ExampleOutput--- PASS: ExampleOutput (0.00s)PASSBenchmarkDiv  100000000         16.2 ns/op--- BENCH: BenchmarkDiv  div_test.go:27: run times: 1  div_test.go:27: run times: 100  div_test.go:27: run times: 10000  div_test.go:27: run times: 1000000  div_test.go:27: run times: 100000000BenchmarkDiv_Sleep  100000000         16.4 ns/op--- BENCH: BenchmarkDiv_Sleep  div_test.go:34: run times: 1  div_test.go:34: run times: 100  div_test.go:34: run times: 10000  div_test.go:34: run times: 1000000  div_test.go:34: run times: 100000000Teardown ... Doneok    github.com/zddhub/hellogo/test  3.305s

木乙言己 zddhub 出品

微信号: zddnotes
Just for fun!

文章只写给自己,如果你也喜欢,欢迎扫描以下二维码关注哦~

logo

转载地址:http://iccol.baihongyu.com/

你可能感兴趣的文章
Hadoop上小文件存储处理
查看>>
优秀的开源系统恢复软件
查看>>
《网页设计与前端开发 Dreamweaver+Flash+Photoshop+HTML+CSS+JavaScript 从入门到精通》——2.3 HTML头部标记head...
查看>>
《Adobe Flash CS6中文版经典教程》——1.11 保存影片
查看>>
Java核心技术卷I基础知识3.6.3 不可变字符串
查看>>
《大数据导论》一2.3 业务流程管理
查看>>
Android--短信拦截及IP拨号
查看>>
线程的优先级
查看>>
AM335x(TQ335x)学习笔记——WM8960声卡驱动移植
查看>>
从EXCHANGE 2010的DAG中删除其中一个MEMBER
查看>>
Ehcache学习笔记
查看>>
Tomcat 内存溢出对应解决方式
查看>>
Mac下 Thinkphp3.2 语言包问题
查看>>
你意想不到的的编程问题
查看>>
Web Service学习总结
查看>>
新手学JAVA(七)----Override VS Overload
查看>>
二、引入字体图标--iconfont
查看>>
阿里巴巴实习生招聘开始啦
查看>>
浏览器的线程和进程
查看>>
Java笔试题JVM部分
查看>>