一、Go testing
标准库
Go 语言提供了 testing
标准库用于至此 Go 语言代码的测试,在编写 Go 语言的测试时需要遵循两个规范:
- Go 的测试代码和被测试代码在同一目录下,不同于 Java 的测试代码是单独在 test 包下。
- Go 的测试代码所在文件要添加后缀
_test
,且测试代码中函数的名字要以TestXxx
命名
. ├── zulu.go └── zulu_test.go 0 directories, 2 files 复制代码
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 } 复制代码
// 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
方法来输出错误信息
数据驱动测试
上述代码中仅仅执行了一次测试用例,在实际项目中会针对同一个测试用例使用不同的数据进行多次测试
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 != %d\n", sum, param.expect) t.Errorf("出现错误的数据为:%v, %v\n", 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 != %d\n", sum, param.expect) t.Errorf("出现错误的数据为:%v, %v\n", param.x, param.y) } if param.x == 3 { t.Skipf("参数为 %v\n", param.x) } } } 复制代码
执行上述代码,输出结果如下:
在 if 条件满足时,使用 Skipf
函数跳过并终止执行测试。