go 单元测试(一)

单元测试

Go 语言测试框架可以让我们很容易地进行单元测试,但是需要遵循下面的规则:

  1. 含有单元测试代码的 go 文件必须以 _test.go 结尾,Go 语言测试工具只认符合这个规则的文件。

  2. 单元测试的函数名必须以 Test 开头,是可导出的、公开的函数,测试函数的签名必须接收一个指向 testing.T 类型的指针,并且不能返回任何值。

    func TestFibonacci(t *testing.T) {
        // ...
    }
    
  3. 单元测试文件名 _test.go 前面的部分最好是被测试的函数所在的 go 文件的文件名,比如下面示例中单元测试文件叫 main_test.go,因为测试的 Fibonacci 函数在 main.go 文件里。 函数名最好是 Test + 要测试的函数名,比如例子中是 TestFibonacci,表示测试的是 Fibonacci 这个函数。

  • ch/fibonacci.go

    package main
    
    func Fibonacci(n int) int {
        if n < 0 {
            return 0
        }
    
        if n == 0 {
            return 0
        }
    
        if n == 1 {
            return 1
        }
    
        return Fibonacci(n-1) + Fibonacci(n-2)
    }
    
  • ch/fibonacci_test.go

    package main
    import "testing"
    
    func TestFibonacci(t *testing.T) {
        // 预先定义的一组斐波那契数列作为测试用例(表驱动)
        caseMap := map[int]int{
          0: 0,
          1: 1,
          2: 1,
          3: 2,
          4: 3,
          5: 5,
          6: 8,
          7: 13,
          8: 21,
        }
    
        for k, v := range caseMap {
            fib := Fibonacci(k)
            if v == fib {
                t.Logf("结果正确:n为%d,值为%d", k, fib)
            } else {
                t.Errorf("结果错误:期望%d,但是计算的值是%d", v, fib)
            }
        }
    }
    

    t.Error = Log + Fail
    t.Errorf = Logf + Fail
    t.Fatal = Log + FailNow
    t.Fatalf = Logf + FailNow

运行单元测试:

# go test -v .
  === RUN   TestFibonacci
    fibonacci_test.go:22: 结果正确:n为0,值为0
    fibonacci_test.go:22: 结果正确:n为2,值为1
    fibonacci_test.go:22: 结果正确:n为5,值为5
    fibonacci_test.go:22: 结果正确:n为6,值为8
    fibonacci_test.go:22: 结果正确:n为8,值为21
    fibonacci_test.go:22: 结果正确:n为9,值为34
    fibonacci_test.go:22: 结果正确:n为1,值为1
    fibonacci_test.go:22: 结果正确:n为3,值为2
    fibonacci_test.go:22: 结果正确:n为4,值为3
    fibonacci_test.go:22: 结果正确:n为7,值为13
  --- PASS: TestFibonacci (0.00s)
  PASS
  ok      ch18/main   0.002s

-v 参数会显示每个用例的测试结果。

断言

Go 语言官方库并没有提供断言的功能,官方认为这可能导致用户懒于思考良好的错误处理和汇报。

但没有断言实在是不方便,所以我们可以使用第三方库 testify 中的 assert 包来实现:

package main
import (
    "github.com/stretchr/testify/assert"
    "testing"
)

func TestFibonacci(t *testing.T) {
    // 预先定义的一组斐波那契数列作为测试用例(表驱动)
    caseMap := map[int]int{
        0: 0,
        1: 1,
        2: 1,
        3: 2,
        4: 3,
        5: 5,
        6: 8,
        7: 13,
        8: 21,
    }

    for k, v := range caseMap {
        fib := Fibonacci(k)
        assert.Equal(t, fib, v)
    }
}

常用的 assert 有:

  • assert.Equal
  • assert.NotEqual
  • assert.Zero
  • assert.NotZero
  • assert.Nil
  • assert.NotNil

同时 testify 还提供了 require 包,和 assert 包的区别是:require包中断言函数一旦执行失败便会导致测试退出,后续的测试代码将无法继续执行。

子测试

TODO

suite

Go testing包没有引入testsuite(测试套件) 或 testcase(测试用例) 的概念,只有 Test 和 SubTest。testify 的suite包为我们提供了一种基于suite/case 结构组织测试代码的方式。

TODO

运行项目下的所有测试用例

在项目根目录下执行go test ./...

指定运行部分测试

如果只想运行一部分测试,我们可以在命令时指定:

# go test -run TestFibonacci

并且支持部分通配符*,和部分正则表达式,例如^$

测试覆盖率以及发布报告

-cover参数可以查看覆盖率。
如果想要测试覆盖率的报告,那么首先:

go test test.go -coverprofile=covprofile

接着再使用工具解析上面的报告,将其转换为html结果网页

go tool cover -html=covprofile -o coverage.html
编译测试为可执行文件

有时,我们编写的测试文件,需要在不同的测试机器上运行,那么可以使用

go test -c 

将测试编译为可执行文件。

如何调试测试
  • 方法一
    # dlv test
    
  • 方法二
    使用 go test -c 将测试编译为可执行文件,然后再使用 dlv 调试。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Go怎么写测试用例 开发程序其中很重要的一点就是测试,我们如何保证代码质量,如何保证每个函数都是可运行的,运行结果...
    Carrism阅读 6,485评论 0 3
  • 大家好,我叫谢伟,是一名程序员。 最近更新不是很频繁,主要是我手头有好些事需要解决,比如更换环境,比如出去见识人,...
    谢小路阅读 2,224评论 2 8
  • 在*_test.go文件中,有三种类型的函数:测试函数、基准测试(benchmark)函数、示例函数。一个测试函数...
    一斗阅读 1,701评论 0 0
  • Go自带了测试框架和工具,在testing包中,以便完成单元测试(T类型)和性能测试(B类型)。 一般测试代码放在...
    涵仔睡觉阅读 21,428评论 0 17
  • 本文说明go语言自带的测试框架未提供或者未方便地提供的测试方案,主要是用于解决写单元测试中比较头痛的依赖问题。也就...
    茶浅呀阅读 418评论 0 1