Go语言之单元测试


一、问题引入

如果让你测试一个函数或者模块,你会怎么做呢?如下:

package main

import "fmt"

// 被测试的函数
func calAdd(n1 int, n2 int) int {

    res := n1 + n2
    return res

}

func main() {
    // 传统测试方式,在main函数中调用,看输出结果
    res := calAdd(1, 2)
    if res != 3 {
        fmt.Printf("calAdd函数错误,期望值是%v,返回值是%v", 3, res)
    } else {
        fmt.Printf("calAdd函数正确,期望值是%v,返回值是%v", 3, res)

    }
}

可以看到在主函数中对被测试函数进行测试,那么会存在一些弊端:

  • 与主函数main进行了绑定
  • 一旦有多个被测试项,都要更改主函数的代码
  • 如果项目正在运行过程中,还需要停止主函数才能继续测试

所以就需要一个专门用于测试的框架来帮助我们解决上面的问题。

二、testing测试框架

1、什么是testing

testing 提供对 Go 包的自动化测试的支持。通过 `go test` 命令,能够自动执行如下形式的任何函数:

func TestXxx(*testing.T)

其中 Xxx 可以是任何字母数字字符串(但第一个字母不能是 [a-z]),用于识别测试例程。

在这些函数中,使用 Error, Fail 或相关方法来发出失败信号。

要编写一个新的测试套件,需要创建一个名称以 _test.go 结尾的文件,该文件包含 `TestXxx` 函数,如上所述。 将该文件放在与被测试的包相同的包中。该文件将被排除在正常的程序包之外,但在运行 “go test” 命令时将被包含。 有关详细信息,请运行 “go help test” 和 “go help testflag” 了解。

2、快速入门

  • 目录结构
|─test
|       cal.go
|       cal_test.go
  • cal.go 业务函数
package abc

func calAdd(n1 int, n2 int) int {

    res := n1 + n2
    return res

}
  • cal_test.go 测试套件
package abc

import (
    "testing"
)

func TestCalAdd(t *testing.T) {
    res := calAdd(1, 2)
    if res != 3 {
        t.Fatalf("calAdd函数错误,期望值是%v,返回值是%v", 3, res)
    } else {
        t.Logf("calAdd函数正确,期望值是%v,返回值是%v", 3, res)

    }
}

在上面的代码中可以看到:

  • cal_test.go测试套件中并没有引入calAdd函数,但是可以识别,原因就是将测试套件cal_test.go和与cal.go放在同一个包abc下
  • 测试套件中的测试用例必须以Test开头,这样方便识别具体的测试用例

3、注意事项

  • 测试套件必须以_test.go结尾
  • 测试套件中的测试用例必须以Test开头,但后面的第一个不能是小写字母[a-z]
  • 一个测试套件文件中可以有多个测试用例函数

4、测试方法

进入到test文件夹:

  • 所有测试用例
go test -v  // 执行所有的测试套件中的所有测试用例
  • 测试单个文件
go test -v cal_test.go cal.go
  • 测试单个方法
go test -v -test.run TestCalAdd