当我编写接口时,通常可以方便地在与接口相同的包中定义我的测试,然后定义实现接口集的多个包,例如.
package/
package/impl/x <-- Implementation X
package/impl/y <-- Implementation Y
Run Code Online (Sandbox Code Playgroud)
有没有一种简单的方法可以在子包中运行相同的测试套件(在本例中,位于package/*_ test.go中)?
我到目前为止提出的最佳解决方案是添加一个测试包:
package/tests/
Run Code Online (Sandbox Code Playgroud)
它实现了测试套件,并在每个实现中进行测试以运行测试,但这有两个缺点:
1)包/测试中的测试不在_test.go文件中,最终成为实际库的一部分,由godoc等记录.
2)包/测试中的测试由自定义测试运行器运行,该测试运行器必须基本上复制'go test'的所有功能以扫描go测试并运行它们.
看起来像一个非常俗气的解决方案.
有没有更好的方法呢?
我真的不喜欢使用单独的测试库.如果您有一个接口,并且每个接口都有通用测试,那么实现该接口的其他人也可能希望使用这些测试.
您可以创建"package/test"包含函数的包
// functions needed for each implementation to test it
type Tester struct {
func New() package.Interface
func (*package.Interface) Done()
// whatever you need. Leave nil if function does not apply
}
func TestInterface(t *testing.T, tester Tester)
Run Code Online (Sandbox Code Playgroud)
请注意,签名TestInterface与go test期望的不匹配.现在,为每个包package/impl/x添加一个文件generic_test.go:
package x
import "testing"
import "package/test"
// run generic tests on this particular implementation
func TestInterface(t *testing.T) {
test.TestInterface(t,test.Tester{New:New})
}
Run Code Online (Sandbox Code Playgroud)
New()您的实现的构造函数在哪里.这种方案的优点是
go test兼容的(大加!)当然,在某些情况下,您需要更复杂的TestInterface功能,但这是基本的想法.