Golang 与子测试 #149
lyyyuna
started this conversation in
Show and tell
Golang 与子测试
#149
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
前言
表格驱动测试可谓是最受欢迎的测试方法了,它抽取了相似用例的公共步骤,结构清晰,维护简单,比如:
但是这种写法有着一个致命的缺陷,你无法像之前一样选择某个用例执行,即不支持
go test -run regex
命令行来选择只执行第一个或第二个测试用例。Go 1.7
中加入了子测试的概念,以解决该问题。什么是 Go 的子测试
子测试在
testing
包中由 Run 方法 提供,它有俩个参数:子测试的名字和子测试函数,其中名字是子测试的标识符。子测试和其他普通的测试函数一样,是在独立的 goroutine 中运行,测试结果也会计入测试报告,所有子测试运行完毕后,父测试函数才会结束。
如何使用
t.Run
使用
t.Run
重构前言中的测试代码,代码变动了不少:首先我们修改了定义用例的结构体,加入了
string
类型的name
属性。这样每个用例都有了自己的名字来标示自己。例如,第一个用例由于参数arg1
大于参数arg2
,所以被命名称FirstOlderThanSecond
。然后在
for
循环中,我们把整个测试逻辑包裹在t.Run
块中,并把用例名作为第一个参数。运行该测试,可得:
$ go test -v -count=1 === RUN TestOlder === RUN TestOlder/FirstOlderThanSecond === RUN TestOlder/SecondOlderThanFirst --- PASS: TestOlder (0.00s) --- PASS: TestOlder/FirstOlderThanSecond (0.00s) --- PASS: TestOlder/SecondOlderThanFirst (0.00s) PASS ok person 0.004s
从结果中我们发现,
TestOlder
派生出另外两个子测试函数:TestOlder/FirstOlderThanSecond
和TestOlder/SecondOlderThanFirst
。在这两个子测试结束之前,TestOlder
都不会结束。子测试函数的测试结果在终端里是缩进的,且测试用例的名字都以
TestOlder
开头,这些都用来凸显测试用例之间的父子关系。go test
选择子测试运行在调试特定测试用例或复现某个 bug 时我们常用
go test -run=regex
来指定。子测试regex
的命名规则和上一节中测试结果一致:父测试名/子测试名
。比如可用以下命令执行子测试
FirstOlderThenSecond
:如果要执行某个父测试下的所有子测试,可键入:
Setup 和 Teardown 和 TestMain
使用过其他测试框架的同学一定不会对
Setup
和Teardown
陌生,这几乎是测试框架的标配。而testing
包长期以来在这块是缺失的,我们无法为所有的测试用例添加一些公共的初始化和结束步骤。引入t.Run
之后,我们便可以实现缺失的功能。请看下面的例子,在子测试开始时,先调用
setupSubtest(t)
做初始化工作,然后使用defer teardownSubtest(t)
保证在t.Run
结束前执行清理工作。运行测试后,可以看到
Setup
和Teardown
在每个子测试中都会被调用:进一步的,每个包的测试文件其实都包含一个“隐藏”的
TestMain(m *testing.M)
函数:若重写该函数,在
m.Run
上下加入Setup
和Teardown
后便得到了全局的初始化和清理函数。Beta Was this translation helpful? Give feedback.
All reactions