当我编写接口(interface)时,在与接口(interface)相同的包中定义我的测试通常很方便,然后定义实现接口(interface)集的多个包,例如。

package/
package/impl/x <-- Implementation X
package/impl/y <-- Implementation Y

是否有一种简单的方法可以在子包中运行相同的测试套件(在这种情况下,位于 package/*_test.go 中)?

到目前为止,我想出的最佳解决方案是添加一个测试包:
package/tests/

它实现了测试套件,并在每个实现中进行了测试以运行测试,但这有两个缺点:

1) package/tests 中的测试不在 _test.go 文件中,最终成为实际库的一部分,由 godoc 等记录。

2) package/tests 中的测试由自定义测试运行器运行,它必须基本上复制 go test 的所有功能来扫描 go 测试并运行它们。

似乎是一个非常俗气的解决方案。

有没有更好的方法来做到这一点?

最佳答案

我真的不喜欢使用单独的测试库的想法。如果您有一个接口(interface)并且您对每个接口(interface)都有通用测试,那么实现该接口(interface)的其他人也可能喜欢使用这些测试。

您可以创建一个包含函数的包 "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)

请注意,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})
}

其中 New() 是您实现的构造函数。这种方案的优点是
  • 你的测试对于实现你的接口(interface)的任何人都是可重用的,即使是来自其他包
  • 很明显,您运行了通用测试套件
  • 测试用例是实现的地方,而不是另一个模糊的地方
  • 如果一个实现需要特殊的初始化或类似的东西,代码可以很容易地适应
  • 兼容 go test(大加分!)

  • 当然,在某些情况下,您需要更复杂的 TestInterface 函数,但这是基本思想。

    关于go - 如何在 go 中为多个包提供一个通用的测试套件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15897803/

    10-17 01:38