一、Go testing
标准库
Go 语言提供了 testing
标准库用于至此 Go 语言代码的测试,在编写 Go 语言的测试时需要遵循两个规范:
- Go 的测试代码和被测试代码在同一目录下,不同于 Java 的测试代码是单独在 test 包下。
- Go 的测试代码所在文件要添加后缀
_test
,且测试代码中函数的名字要以TestXxx
命名
.
├── zulu.go
└── zulu_test.go
0 directories, 2 files
代码语言:javascript复制func TestXxx(t *testing.T) {
// 测试代码
}
TestXxx
函数的参数除了可以是 *testing.T
外,还可以选择 *testing.B
、*testing.B
和 *testing.M
等,它们都表示不同类型的测试。
二、第一个 Go 的单元测试
新建一个 test
目录,在该目录下新建 zulu.go
和 zulu_test.go
,在这两个文件中增加代码
// zulu.go
package main
import "fmt"
func Add(x, y int) int {
fmt.Println("Add 方法被调用")
return x y
}
代码语言:javascript复制// zulu_test.go
package main
import "testing"
func TestAdd(t *testing.T) {
x, y := 2, 3
sum := Add(x, y)
expect := 2 3
if sum != expect {
t.Error("失败")
}
}
执行 zulu_test.go
文件
根据输出内容,可以确定测试执行成功。
上述代码中通过 t.Error
来输出错误信息,也可以使用 Fail
方法来输出错误信息
数据驱动测试
上述代码中仅仅执行了一次测试用例,在实际项目中会针对同一个测试用例使用不同的数据进行多次测试
代码语言:javascript复制func TestAdd(t *testing.T) {
// 构造一个参数结构体的切片
params := []Param {
{1, 2, 3},
{5, 6, 11},
{3, 7, 10},
{2, 6, 8},
{2, 2, 3},
}
for _, param := range params {
sum := Add(param.x, param.y)
if sum != param.expect {
t.Errorf("%d != %dn", sum, param.expect)
t.Errorf("出现错误的数据为:%v, %vn", param.x, param.y)
}
}
}
type Param struct {
x int
y int
expect int
}
执行上述代码,输出结果如下:
根据结果可以确定,TestAdd
方法调用了 5 次,最后一次参数为 2,2
的时候用例执行失败。
三、testing.T
类型
在上面的单元测试中,TestXxx 函数传递的参数为 *testing.T
,该参数用于管理测试状态并支持格式化输出测试日志。
当 TestXxx 函数返回时,T 调用 TB 接口中的 FailNow
、 Fatal
、Fatalf
、SkipNow
、Skip
、Skipf
中的任意一个时,则宣告该测试函数结束。
当测试用例结果断言失败时:
方法 | 说明 |
---|---|
Fail | 测试失败,剩下用例继续执行 |
FailNow | 测试失败,测试中断 |
SkipNow | 跳过测试,测试中断 |
Log | 输出信息 |
Logf | 格式化输出信息 |
Skip | Log SkipNow |
Skipf | Logf SkipNow |
Error | Log Fail |
Errorf | Logf Fail |
Fatal | Log FailNow |
Fatalf | Logf FailNow |
func TestAdd(t *testing.T) {
// 构造一个参数结构体的切片
params := []Param {
{1, 2, 3},
{5, 6, 11},
{3, 7, 10},
{2, 6, 8},
{2, 2, 3},
}
for _, param := range params {
sum := Add(param.x, param.y)
if sum != param.expect {
t.Errorf("%d != %dn", sum, param.expect)
t.Errorf("出现错误的数据为:%v, %vn", param.x, param.y)
}
if param.x == 3 {
t.Skipf("参数为 %vn", param.x)
}
}
}
执行上述代码,输出结果如下:
在 if 条件满足时,使用 Skipf
函数跳过并终止执行测试。