前言
在实际写 Go 的单元测试过程中,我们有时候需要在执行测试之前调用 setUp 函数(加载配置完成初始化操作)和测试执行之后执行 tearDown 函数(关闭释放连接或者资源),通过可以分为以下三个情况:
- 所有测试用例一起执行前后
- 分组测试用例执行前后
- 单个测试用例执行前后
所有测试用例执行前后
Go 的 testing 的标准库里提供了一个 TestMain
的方法
func TestMain(m *testing.M)
一个最小的实现如下:
func setUp() {
// set up
}
func tearDown() {
// tear down
}
func TestMain(m *testing.M) {
setUp()
code := m.Run()
tearDown()
os.Exist(code)
}
就像最先说到的那样,我们通常会在全局的 setUp
里完成一些资源的连接或者加载,完成一些其他测试用例需要使用的共同的实例的初始化,然后在 tearDown
完成资源的释放和回收
分组测试用例执行前后
有时候我们会进行分组测试,这个时候配合 t.Run
使用完成 subtest
,对测试用例进行归类,与全局的 setUp 和 tearDown 不同的是,在这种场景下每个分组需要的资源可能略微不同,这个时候我们就需要有差异化的初始化了,一个典型的例子如下:
func TestSomethingWhenGivenCondition(t *testing.T) {
// set up
t.Run("特性1", func(t *testing.T) {
})
t.Run("特性2", func(t *testing.T) {
// Subtest 2 code goes here
})
// tear down
}
单个测试用例执行前后
go 的 test 标准库并没有提供在每个测试用例执行前后的函数,对于这种场景,就需要我们自己构建对应的函数去完成了,一个最小的实现方法通常如下:
func setupTestCase(t *testing.T) func(t *testing.T) {
// set up
// code
return func(t *testing.T) {
// code
// tear down
}
}
func TestA(t *testing.T) {
teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)
// code
}
每次测试用例执行前后的时候,对应的 set up 的 tear down 的代码都会被执行。除此之外,也有借助 t.Run 去实现这一目的的
func testCase(test func(t *testing.T, c *testContext)) func(*testing.T) {
return func(t *testing.T) {
context := &testContext{}
context.beforeEach()
defer context.afterEach()
test(t, context)
}
}
func TestSomething(t *testing.T) {
t.Run("Some test case", testCase(func(t *testing.T, c *testContext) {
// Test code goes here which can leverage the context
}))
}
参考
前言
在实际写 Go 的单元测试过程中,我们有时候需要在执行测试之前调用 setUp 函数(加载配置完成初始化操作)和测试执行之后执行 tearDown 函数(关闭释放连接或者资源),通过可以分为以下三个情况:
所有测试用例执行前后
Go 的 testing 的标准库里提供了一个
TestMain
的方法一个最小的实现如下:
就像最先说到的那样,我们通常会在全局的
setUp
里完成一些资源的连接或者加载,完成一些其他测试用例需要使用的共同的实例的初始化,然后在tearDown
完成资源的释放和回收分组测试用例执行前后
有时候我们会进行分组测试,这个时候配合
t.Run
使用完成subtest
,对测试用例进行归类,与全局的 setUp 和 tearDown 不同的是,在这种场景下每个分组需要的资源可能略微不同,这个时候我们就需要有差异化的初始化了,一个典型的例子如下:单个测试用例执行前后
go 的 test 标准库并没有提供在每个测试用例执行前后的函数,对于这种场景,就需要我们自己构建对应的函数去完成了,一个最小的实现方法通常如下:
每次测试用例执行前后的时候,对应的 set up 的 tear down 的代码都会被执行。除此之外,也有借助 t.Run 去实现这一目的的
参考