我已经为Web API实现了几个包,每个包都有自己的测试用例。当使用go test ./api/pkgname
测试每个包时,测试通过。如果我想使用go test ./api/...
测试用例一次运行所有测试,则总是失败。
在每个测试用例中,我使用DROP SCHEMA public CASCADE
后跟CREATE SCHEMA public
重新创建整个架构并应用所有迁移。测试套件随机报告错误,说关系/表不存在,所以我猜每个测试套件(每个包)都以某种方式并行运行,从而弄乱了数据库状态。
我尝试传递一些测试标记,例如go test -cpu 1 -parallel 0 ./src/api/...
但没有成功。
这里的问题可能是并行运行的测试,如果是,我该如何强制执行串行执行?
的更新 的
目前我使用此变通方法来运行测试,但我仍然想知道是否有更好的解决方案
find <dir> -type d -exec go test {} \;
答案 0 :(得分:32)
正如其他人所指出的那样,-parallel并不能完成这项任务(它只适用于包中)。但是,您可以使用标志-p = 1来串行运行包测试。这在此处记录:
http://golang.org/src/cmd/go/testflag.go
但是(afaict)不在命令行上,去帮助等等。我不确定它是否意味着要坚持下去(虽然我认为如果删除它, - 并行应该被修复。)
答案 1 :(得分:9)
使用go工具可以使用* _test.go文件中包含单元测试的约定,使运行单元测试更容易。因为它假定它们是单元测试,所以它也假定它们是密封的。听起来你的测试要么不是单元测试,要么是违反单元测试应该满足的假设。
如果您认为这些测试是单元测试,那么您可能需要一个模拟数据库来进行单元测试。数据库中的模拟,最好是内存,将确保单元测试是密封的,不会受到其他单元测试的干扰。
如果您认为这些测试是集成测试,那么最好不要使用go工具进行这些测试。您可能想要的是创建一个单独的测试二进制文件,其运行可以控制并在那里编写集成测试脚本。
好消息是在Go中创建模拟非常容易。更改您的代码以获取您关心数据库的方法的接口,然后编写该接口的内存实现以进行测试,并将其传递到您要测试的应用程序代码中。
答案 2 :(得分:3)
为了澄清,@ Jeremy的回答仍然是被接受的答案:
由于我的集成测试仅在一个软件包(api
)上运行,因此我最后删除了单独的测试二进制文件,并创建了一个模式来分隔测试类型:
TestX
名称Test_X
我创建了shell脚本(utest.sh
/ itest.sh
)来运行其中任何一个。
go test -run="^(Test|Benchmark)[^_](.*)"
go test -run"^(Test|Benchmark)_(.*)"
go test