gpt4 book ai didi

testing - Go包之间如何共享测试接口(interface)?

转载 作者:IT王子 更新时间:2023-10-29 01:41:31 25 4
gpt4 key购买 nike

Go 不会在不同包的测试文件之间共享代码,因此不会自动重用测试接口(interface)的定义。我们如何在实践中解决这个问题?

使用testing/quick的例子:

foo/foo.go:

package foo

type Thing int

const (
X Thing = iota
Y
Z
)

bar/bar.go:

package bar

import (
"foo"
)

type Box struct {
Thing foo.Thing
}

我们想对 foo 进行属性测试,所以我们在 Thing 上定义了 testing/quick.Generate:

foo_test.go:

package foo

import (
"math/rand"
"reflect"
"testing"
"testing/quick"
"time"
)

func (_ Thing) Generate(r *rand.Rand, sz int) reflect.Value {
return reflect.ValueOf(Thing(r.Intn(3)))
}

func TestGenThing(t *testing.T) {
r := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
for i := 0; i < 5; i++ {
val, _ := quick.Value(reflect.TypeOf(Thing(0)), r)
tng, _ := val.Interface().(Thing)
t.Logf("%#v\n", tng)
}
}

quick.Value 按预期返回 [0,3) 范围内的 Thing:

$ go test -v foo
=== RUN TestGenThing
--- PASS: TestGenThing (0.00s)
foo_test.go:20: 0
foo_test.go:20: 1
foo_test.go:20: 2
foo_test.go:20: 1
foo_test.go:20: 2
PASS
ok foo 0.026s

让我们也对 bar 进行属性测试:

package bar

import (
"math/rand"
"reflect"
"testing"
"testing/quick"
"time"

"foo"
)

func (_ Box) Generate(r *rand.Rand, sz int) reflect.Value {
val, _ := quick.Value(reflect.TypeOf(foo.Thing(0)), r)
tng, _ := val.Interface().(foo.Thing)
return reflect.ValueOf(Box{tng})
}

func TestGenBox(t *testing.T) {
r := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
for i := 0; i < 5; i++ {
val, _ := quick.Value(reflect.TypeOf(Box{}), r)
box, _ := val.Interface().(Box)
t.Logf("%#v\n", box)
}
}

但是 Box.Generate 坏了。 foo_test.gobar_test.go 不可用,所以 quick.Value() 不使用 Thing.Generate( ):

$ GOPATH=$PWD go test -v bar
=== RUN TestGenBox
--- PASS: TestGenBox (0.00s)
bar_test.go:24: bar.Box{Thing:3919143124849004253}
bar_test.go:24: bar.Box{Thing:-3486832378211479055}
bar_test.go:24: bar.Box{Thing:-3056230723958856466}
bar_test.go:24: bar.Box{Thing:-847200811847403542}
bar_test.go:24: bar.Box{Thing:-2593052978030148925}
PASS
ok bar 0.095s

有解决办法吗?人们如何在实践中使用 testing/quick(或任何其他具有接口(interface)的测试库)?

最佳答案

包之间共享的任何代码都必须在非测试文件中。但这并不意味着它必须包含在任何最终版本中;你可以使用 build constraints从正常构建中排除文件,以及 build tags在运行测试时包括它们。例如,您可以将共享测试代码放在前缀为:

的文件中
//+build testtools

package mypackage

(但没有命名为_test.go)。当您构建时,这将不会包含在构建中。当你测试时,你会使用类似的东西:

go test -tags "testtools" ./...

这将在构建中包含受限文件,从而使共享代码可用于测试。

关于testing - Go包之间如何共享测试接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44192688/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com