Testing 包测试的串行执行

Testing 包测试的串行执行,testing,go,Testing,Go,我已经为web API实现了几个包,每个包都有自己的测试用例。使用go test./api/pkgname测试每个包时,测试通过。如果我想使用go test./api/…一次运行所有测试,测试用例总是失败 在每个测试用例中,我使用DROP schema public CASCADE,然后使用CREATE schema public重新创建整个模式,并应用所有迁移。测试套件会随机报告错误,说关系/表不存在,所以我猜每个测试套件(每个包)都是以某种方式并行运行的,从而弄乱了数据库状态 我试图传递一些

我已经为web API实现了几个包,每个包都有自己的测试用例。使用
go test./api/pkgname
测试每个包时,测试通过。如果我想使用
go test./api/…
一次运行所有测试,测试用例总是失败

在每个测试用例中,我使用
DROP schema public CASCADE
,然后使用
CREATE schema public
重新创建整个模式,并应用所有迁移。测试套件会随机报告错误,说关系/表不存在,所以我猜每个测试套件(每个包)都是以某种方式并行运行的,从而弄乱了数据库状态

我试图传递一些测试标志,如
go-test-cpu1-parallel 0./src/api/…
,但没有成功

这里的问题是并行运行的测试吗?如果是,我如何强制串行执行

更新:

目前我使用这个解决方案来运行测试,但我仍然怀疑是否有更好的解决方案

find <dir> -type d -exec go test {} \;
find-type d-exec-go-test{};

提供go工具是为了使用*\u test.go文件中包含单元测试的约定,使运行单元测试更容易。因为它假设它们是单元测试,所以它也假设它们是密封的。听起来你的测试不是单元测试,或者是违反了单元测试应该满足的假设

如果您想让这些测试成为单元测试,那么您可能需要一个模拟数据库来进行单元测试。数据库的模拟(最好是内存中的模拟)将确保单元测试是密封的,并且不会受到其他单元测试的干扰

如果您想让这些测试成为集成测试,那么最好不要在这些测试中使用go工具。您可能希望创建一个单独的测试二进制文件,您可以在其中控制并编写集成测试脚本


好消息是,在围棋中创建一个mock非常容易。更改您的代码,使用您关心的数据库方法创建一个接口,然后为测试目的编写该接口的内存实现,并将其传递到您要测试的应用程序代码中。

只是澄清一下,@Jeremy的答案仍然是公认的:

由于我的集成测试只在一个包(
api
)上运行,因此我最终删除了单独的测试二进制文件,并创建了一个模式,通过以下方式分离测试类型:

  • 单元测试使用普通的
    TestX
    名称
  • 集成测试使用
    Test_X
我创建了shell脚本(
utest.sh
/
itest.sh
)来运行这两个脚本

  • 对于单元测试
    go test-run=“^(测试|基准测试)[^ |](.*)”
  • 对于集成测试
    go test-run“^(测试|基准测试)U124;(.*)”
  • 使用正常的
    go测试运行这两个

正如其他人所指出的那样,-parallel不起作用(它只在包内工作)。但是,您可以使用标志-p=1来运行系列的包测试。这里记录了这一点:


但是(afaict)不在命令行、go help等中。我不确定它是否要保留(尽管我认为如果它被删除,-parallel应该被修复。)

也许这不是一个go问题,而是一个测试问题。测试不应该有全局状态(比如连接到数据库),因此应该能够并行运行。那么,您建议如何测试依赖于数据库的API?模拟一切都会破坏测试的目的。我自己不喜欢全局测试状态,但我看不到其他选项。虽然理想情况下这些测试是单元测试,但我看不到在多个包上运行时忽略-parallel=0的任何理由。这听起来像是真正的错误。是的,我知道我可以模拟它,但我实际上想访问数据库,这就是为什么我可能会将测试移动到单独的二进制文件中。实际上设置单独的集成测试
main.go
非常容易,因为
testing
exports
testing.main
。是的,这就是我建议它的部分原因:-感谢后续工作,这在遇到相同场景时非常有用。这在完全相同的场景中对我们非常有效。非常有效!虽然我在你链接到的页面中看不到任何对该标志的引用。也许他们删除了这方面的文档?p标志显示在
go help build
的输出中。非常感谢,这对我很有用!我在考虑各种疯狂的解决方法,比如为每个包创建一个单独的数据库(yikes)——很高兴它最终变得如此简单。顺便说一句,现在链接是404