子测试提供了一种在测试函数中执行多个测试的能力.比如原来有TestA TestB和
TestC三个测试函数.每个函数都需要做一些相同的测试化工作.那么可以利用子测试
将这三个合并到一个测试中.这样只需要做一次初始化工作.
package goTest
import "testing"
func sub1(t *testing.T) {
var a = 1
var b = 2
var expected = 3
actucal := Add(a, b)
if actucal != expected {
t.Errorf("Add(%d, %d) = %d; want %d", a, b, actucal, expected)
}
}
func sub2(t *testing.T) {
var a = 1
var b = 2
var expected = 3
actucal := Add(a, b)
if actucal != expected {
t.Errorf("Add(%d, %d) = %d; want %d", a, b, actucal, expected)
}
}
func sub3(t *testing.T) {
var a = 1
var b = 2
var expected = 3
actucal := Add(a, b)
if actucal != expected {
t.Errorf("Add(%d, %d) = %d; want %d", a, b, actucal, expected)
}
}
func TestSub(t *testing.T) {
t.Run("sub1", sub1)
t.Run("sub2", sub2)
t.Run("sub3", sub3)
}
通过t.run执行了三个子测试.t.run函数声明如下:
func (t *T) Run(name string, f func(t *T)) bool {}
name是参数子测试的名字.t为子测试函数.本例子中run()一直阻塞到f执行结束后才
返回.返回值为f的执行结果.run会启动新的协程来执行f.并阻塞等待f执行结束才返
回.除非f中使用t.Parallel设置子测试为并发.
执行结果:
1.子测试命名规则:
上面的例子可以知道run方法的第一个参数名字为子测试的名字.实际上子测试的内部
命名规则为<父测试名字>/<传递给run的名字>.
2.过滤筛选:
通过测试的名字.可以在执行中过滤一部分测试.
输入指令go test -v -run Sub/sub1
执行结果:
3.子测试并发:
前面的例子测试是共享setup和teardown有一个前提是子测试没有并发.如果子测
试使用t.Parallel指定并发.那么就无法共享teardown了.因为执行顺序很可能是
setup->子测试1->teardown->子测试2...
如果子测试可能并发.则可以把子测试通过Run()在嵌套一层.Run()可以保证其下的
所有子测试执行结束后在返回.
package goTest
import (
"fmt"
"testing"
"time"
)
func parallelTest1(t *testing.T) {
t.Parallel()
time.Sleep(3 * time.Second)
fmt.Println("parallelTest1()")
}
func parallelTest2(t *testing.T) {
t.Parallel()
time.Sleep(2 * time.Second)
fmt.Println("parallelTest2()")
}
func parallelTest3(t *testing.T) {
t.Parallel()
time.Sleep(1 * time.Second)
fmt.Println("parallelTest3()")
}
func TestSubParallel(t *testing.T) {
t.Logf("Setup")
t.Run("group1", func(t *testing.T) {
t.Run("Test1", parallelTest1)
t.Run("Test2", parallelTest2)
t.Run("Test3", parallelTest3)
})
t.Logf("teardown")
}
执行结果:
总结:
子测试是并发执行的.Test1最先执行最后结束.
tear-down在所有子测试结束后才执行.
夜里风雪未停.
撩了繁花惊扰了命.
语雀地址www.yuque.com/itbosunmian… 《Go.》 密码:xbkk 欢迎大家访问.提意见.
如果大家喜欢我的分享的话,可以关注我的微信公众号
念何架构之路