是否可以从非测试go文件中调用测试函数以开始执行测试?
例如,我有一个测试功能:
package API
import "testing"
func TestAPI(t *testing.T) {
...
}
我需要从非测试版文件中调用此文件。
package main
import "../API"
API.TestAPI()
我可以这样做吗?
答案 0 :(得分:0)
Go中有一些很棒的测试模式。不幸的是,您尝试进行测试的方式无法正常工作。
您应该使用命令go test <pkg
运行单元测试。绝对不要从代码内部调用测试。
Go中的单元测试通常有两种主要形式-黑盒单元测试。
白盒测试:从内部测试未导出功能 包装本身。
黑盒测试:从外部测试已导出功能 包,模拟其他包如何与之交互。
如果我有一个要测试的软件包example
。有一个简单的导出功能,可以对提供的数字列表进行汇总。 Sum
函数还使用了一个未导出实用程序函数。
example.go
package example
func Sum(nums ...int) int {
sum := 0
for _, num := range nums {
sum = add(sum, num)
}
return sum
}
func add(a, b int) int {
return a + b
}
example_test.go :黑盒测试
请注意,我正在测试example
软件包,但是测试位于example_test
软件包中。添加_test
可以使Go编译器保持满意,并使其知道这是example
的测试包。在这里,我们只能访问导出的变量和函数,这些变量和函数可以让我们测试外部软件包在导入和使用example
软件包时将经历的行为。
package example_test
import (
"testing"
"example"
)
func TestSum(t *testing.T) {
tests := []struct {
nums []int
sum int
}{
{nums: []int{1, 2, 3}, sum: 6},
{nums: []int{2, 3, 4}, sum: 9},
}
for _, test := range tests {
s := example.Sum(test.nums...)
if s != test.sum {
t.FailNow()
}
}
}
example_internal_test.go :白盒测试
请注意,我正在测试example
软件包,并且测试也位于example
软件包中。这样,单元测试就可以访问未导出的变量和函数。
package example
import "testing"
func TestAdd(t *testing.T) {
tests := []struct {
a int
b int
sum int
}{
{a: 1, b: 2, sum: 3},
{a: 3, b: 4, sum: 7},
}
for _, test := range tests {
s := add(test.a, test.b)
if s != test.sum {
t.FailNow()
}
}
}
我希望这对您如何设置和使用Go的测试框架有更好的了解。为了简化起见,我没有在示例中使用任何外部库,尽管github.com/stretchr/testify是一个非常流行且功能强大的软件包,可以帮助进行单元测试。
答案 1 :(得分:0)
您尝试的可能性是可能的,但不建议使用,因为它取决于Go的testing
库的内部细节,而Go 1兼容保证未涵盖这些细节,这意味着您可能必须针对每个版本的Go调整此方法。
您很少(如果有的话)尝试这样做。我这样做是为了一套API集成测试,我希望它能够作为普通测试运行,但也可以从CLI工具运行,以测试API的第三方实现。现在我已经完成了,现在不确定是否会再次执行。我可能会寻找其他方法。
但是,如果不能劝阻,这是您需要做的:
您的测试必须不要在名为*_test.go
的文件中定义。此类文件无法正常编译。
对于正常的测试用例,您必须触发测试以从名为*_test.go
的文件中运行。
您必须在非测试案例中手动编排测试。
详细信息:
将测试放入非测试文件中。 testing
软件包只是一个标准的软件包,因此很容易在需要的地方包含它:
foo.go
package foo
import "testing"
func SomethingTest(t *testing.T) {
// your tests
}
从*_test.go
文件运行测试:
foo_test.go
func TestSomething(t *testing.T) {
SomethingTest(t)
}
并从非测试文件运行测试。在这里您处于危险境地,因为它要求使用不受Go 1兼容性保证保护的方法。您需要使用人工制作的测试列表来调用testing.MainStart方法。
这还需要实现自己的testing.testDeps
版本,该版本是私有的,但是是一个易于实现的接口。您可以看到我的Go 1.9实现here。
tests := []testing.InternalTest{
{
Name: "TestSomething",
f: SomethingTest,
},
}
m := testing.MainStart(MyTestDeps, tests, nil, nil)
os.Exit(m.Run())
这是一个非常简化的示例,并不意味着完整。但我希望它能使您走上正确的道路。