go 语言测试:表驱动测试 | go 技术论坛-金年会app官方网
编写好的测试并非易事,但是在很多情况下,表格驱动测试可以涵盖很多领域:每一个表条目都是一个完整的测试用例,包含输入和预期结果,有时还包含测试名字等附加信息,以使测试输出易于阅读。如果你发现你自己在写测试用例时使用复制和粘贴,请考虑重构为表驱动测试还是将复制的代码拉出到帮助函数中可能是更好的选择。
给定一张测试用例表,实际测试只是迭代所有表项,并对每个项执行必要的测试。测试代码只编写一次,然后在所有表项上摊销,所以使用正确的错误消息编写仔细的测试是很有意义的。
表驱动测试并不是一个工具、包或者其他任何东西,它只是编写干净测试的一种方式和视角。
表驱动测试用例示例
以下是 fmt
包( )内测试代码中的一个很好的示例:
var flagtests = []struct {
in string
out string
}{
{"%a", "[%a]"},
{"%-a", "[%-a]"},
{"% a", "[% a]"},
{"%#a", "[%#a]"},
{"% a", "[% a]"},
{"
", "[
]"},
{"%1.2a", "[%1.2a]"},
{"%-1.2a", "[%-1.2a]"},
{"% 1.2a", "[% 1.2a]"},
{"%- 1.2a", "[% -1.2a]"},
{"%- 1.2abc", "[% -1.2a]bc"},
{"%-1.2abc", "[%-1.2a]bc"},
}
func testflagparser(t *testing.t) {
var flagprinter flagprinter
for _, tt := range flagtests {
t.run(tt.in, func(t *testing.t) {
s := sprintf(tt.in, &flagprinter)
if s != tt.out {
t.errorf("got %q, want %q", s, tt.out)
}
})
}
}
注意 t.errorf
提供的详细错误消息: 提供其结果和预期结果;输入是子测试名称。当测试失败的时候,即便不用阅读测试代码,也能立马明确是哪个测试失败了以及失败的原因。
t.errorf
的调用不是断言。即使记录了错误,测试仍将继续进行。例如,当使用整数输入测试某个对象时,应该知道函数对所有的输入都会失败,或者只对奇数输入失败,或者对二次幂失败。
并行测试
并行表单测试很简单,但是需要精确性来避免出现错误。请密切注意下面的三个变化,尤其是重声明的 tt
。
package main
import (
"testing"
)
func testtlog(t *testing.t) {
t.parallel() // marks tlog as capable of running in parallel with other tests
tests := []struct {
name string
}{
{"test 1"},
{"test 2"},
{"test 3"},
{"test 4"},
}
for _, tt := range tests {
tt := tt // note: https://github.com/golang/go/wiki/commonmistakes#using-goroutines-on-loop-iterator-variables
t.run(tt.name, func(t *testing.t) {
t.parallel() // marks each test case as capable of running in parallel with each other
t.log(tt.name)
})
}
}
参考文献
参考: