testify可以说是最流行的(从 GitHub star 数来看)Go 语言测试库了。testify提供了很多方便的函数帮助我们做assert和错误信息输出。使用标准库testing,我们需要自己编写各种条件判断,根据判断结果决定输出对应的信息。
testify核心有三部分内容:
assert 子库提供了便捷的断言函数,可以大大简化测试代码的编写。总的来说,它将之前需要判断 + 信息输出的模式:
if got != expected {
t.Errorf("Xxx failed expect:%d got:%d", got, expected)
}
简化为一行断言代码:
assert.Equal(t, got, expected, "they should be equal")
结构更清晰,更可读。熟悉其他语言测试框架的开发者对assert的相关用法应该不会陌生。此外,assert中的函数会自动生成比较清晰的错误描述信息:
func TestEqual(t *testing.T) {
var a = 100
var b = 200
assert.Equal(t, a, b, "")
}
testify提供了对 Mock 的简单支持。Mock 简单来说就是构造一个仿对象,仿对象提供和原对象一样的接口,在测试中用仿对象来替换原对象。这样我们可以在原对象很难构造,特别是涉及外部资源(数据库,访问网络等)。例如,我们现在要编写一个从一个站点拉取用户列表信息的程序,拉取完成之后程序显示和分析。如果每次都去访问网络会带来极大的不确定性,甚至每次返回不同的列表,这就给测试带来了极大的困难。我们可以使用 Mock 技术。
testify提供了测试套件的功能(TestSuite),testify测试套件只是一个结构体,内嵌一个匿名的suite.Suite结构。测试套件中可以包含多个测试,它们可以共享状态,还可以定义钩子方法执行初始化和清理操作。钩子都是通过接口来定义的,实现了这些接口的测试套件结构在运行到指定节点时会调用对应的方法。
我主要用两个包 assert package,require package,他们的唯一差别就是require的函数会直接导致case结束,而assert虽然也标记为case失败,但case不会退出,而是继续往下执行。看一个例子:
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestCase1(t *testing.T) {
name := "Bob"
age := 10
assert.Equal(t, "bob", name)
assert.Equal(t, 20, age)
}
执行:
$ go test
--- FAIL: TestCase1 (0.00s)
assertions.go:254:
Error Trace: main_test.go:13
Error: Not equal:
expected: "bob"
actual : "Bob"
Test: TestCase1
assertions.go:254:
Error Trace: main_test.go:14
Error: Not equal:
expected: 20
actual : 10
Test: TestCase1
FAIL
exit status 1
FAIL testUT 0.009s
在这个例子中我们使用的是assert,可以看到两个assert.Equal()指令都被执行了。
参考: https://www.jb51.net/article/256517.htm
https://www.jianshu.com/p/ad46bbbf877c