前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go test 上篇

go test 上篇

作者头像
用户2937493
发布2019-09-10 17:53:52
6800
发布2019-09-10 17:53:52
举报
文章被收录于专栏:米奇爱编程米奇爱编程

前言

Go语言本身集成了轻量级的测试框架,由go test命令和testing包组成。包含单元测试和压力测试,是保证我们编写健壮Golang程序的有效工具。

演示环境

$ uname -a
Darwin 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64
$ go version
go version go1.12.4 darwin/amd64

示例

老规矩,我会用一个简单的示例演示go test的用法,让大家有一个直观的感受。

$ ls
my.go my_test.go
$ go test -v
=== RUN   TestAbs
--- PASS: TestAbs (0.00s)
PASS
ok      mytest    0.006s

my.go文件内容:

package mytest

func Abs(a int) int {
    if a < 0 {
        return -1*a
    }
    return a
}

my_test.go文件的内容:

package mytest

import "testing"

func TestAbs(t *testing.T) {
    result := Abs(-1)
    if result != 1 {
        t.Errorf("Abs(-1) = %d; want 1", result)
    }
}

可以看出,测试文件是以_test.go结尾的文件,包含函数名TestXXX的文件签名func (t *testing.T)。测试框架会按函数定义的顺序依次执行Test开头的函数。如果测试函数调用错误函数,比如t.Error,t.Fail,那么测试就会认为是失败的。但是不会强制退出,测试程序还是会接着往下运行,除非调用t.Fatal,就会打印错误信息,并且强制退出。go test会自动编译运行_test.go结尾的文件,go build不会编译_test.go结尾的文件,所以不用担心test文件和正式文件定义为同一个包导致包大小增大。

详细用法

go test执行时会编译_test结尾的文件,执行文件中以Test,Benchmark,Example 开头的测试函数。建议_test.go文件和源文件声明为同一个包。单元测试函数TestXXX的参数是testing.T,BenchmarkXXX的参数是testing.B,函数内以b.N作为循环次数,其中N会动态变化。可以通过testing.T的Error,Errorf,Fail,Fatal,Fatalf 来说明测试不通过。

表格驱动测试

上述的示例单元测试用了-1这个测试用例来演示测试用法,但是在实际生产中我们编写一个测试函数肯定会有多种测试用例,各种边界条件,那这种情况应该怎么办呢?难道要每个测试用例拷贝一份上述的测试函数吗,显然是不合适的。这就介绍接下来的表格驱动测试(table driven test):

package mytest

import "testing"

func TestAbs(t *testing.T) {
    var testcases = []struct {
        in int
        out int
    }{
        {-1, 1},
        {0, 0},
        {2, 2},
        {123, 123},
        {-30, -30},
    }
    for _, tc := range testcases {
        result := Abs(tc.in)
        if result != tc.out {
            t.Fatalf("Abs(%d) = %d; want %d", tc.in, result, tc.out)
        }
    }

}

表格的每一项是一个完整的测试用例,包含输入信息和期望的输出结果,有时候还包含测试用例名称等额外信息。这样我们就可以在表格里面编写各种测试用例场景,包括常规场景,边界场景,和一些异常场景。运行结果为:

$ go test -v
=== RUN   TestAbs
--- FAIL: TestAbs (0.00s)
    my_test.go:19: Abs(-30) = 30; want -30
FAIL
exit status 1
FAIL    mytest    0.005s
性能测试

性能测试函数以是Benchmark开头,格式为:

func Benchmark(b *testing.B)

go test 默认是不会运行_test.go文件中的Benchmark函数,需要通过-bench选项开启。演示代码:

package mytest

import "testing"

func BenchmarkAbs(b *testing.B) {
    for i := 0; i < b.N; i++ {
        result := Abs(i)
        if result != i {
            b.Errorf("benchmark faild, abs(%d) result %d, except %d", i, result, i)
        }
    }
}

运行结果:

$ go test -bench=".*"
goos: darwin
goarch: amd64
pkg: mytest
BenchmarkAbs-12        2000000000             0.26 ns/op
PASS
ok      mytest    0.553s

-bench后面跟的是正则表达式,我们可以指定需要匹配运行的benchmark函数,示例中的.*表示运行所有的benchmark函数。

上述结果显示总共运行了0.553s,一共运行了2000000000次,平均每次运行的时间是0.26纳秒。

总结

文章介绍了Go语言自带的go test测试框架的单元测试和性能测试方法。下篇将会讲解gomock模拟实际的生产接口。

参考

https://golang.org/pkg/testing/

https://github.com/golang/go/wiki/TableDrivenTests

https://golang.org/doc/code.html#Testing

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 演示环境
  • 示例
  • 详细用法
    • 表格驱动测试
      • 性能测试
      • 总结
      • 参考
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档