英文:
Trying to run tests in parallel with golang testify/suite fails
问题
我有几个使用testify/suite
包的测试,并且按照以下方式并行执行:
type IntegrationSuite struct {
suite.Suite
}
func TestIntegrationSuite(t *testing.T) {
suite.Run(t, &IntegrationSuite{})
}
func (is *IntegrationSuite) TestSomething() {
is.T().Log("\tIntegration Testing something")
for i := range myTestTable {
i := i
is.T().Run("Testing "+myTestTable[i].scenarioName, func(_ *testing.T) {
is.T().Parallel()
...
})
}
}
func (is *IntegrationSuite) TestSomethingElse() {
is.T().Log("\tIntegration Testing something else")
for i := range myOtherTestTable {
i := i
is.T().Run("Testing "+myOtherTestTable[i].scenarioName, func(_ *testing.T) {
is.T().Parallel()
...
})
}
}
然而,这会导致以下错误:
panic: testing: t.Parallel called multiple times [recovered]
panic: testing: t.Parallel called multiple times
如何在这个特定的包中利用并行性呢?
英文:
I have several tests using testify/suite
package and I execute them in parallel as follows
type IntegrationSuite struct {
suite.Suite
}
func TestIntegrationSuite(t *testing.T) {
suite.Run(t, &IntegrationSuite{})
}
func (is *IntegrationSuite) TestSomething() {
is.T().Log("\tIntegration Testing something")
for i := range myTestTable {
i := i
is.T().Run("Testing "+myTestTable[i].scenarioName, func(_ *testing.T) {
is.T().Parallel()
...
func (is *IntegrationSuite) TestSomethingElse() {
is.T().Log("\tIntegration Testing something else")
for i := range myOtherTestTable {
i := i
is.T().Run("Testing "+myOtherTestTable[i].scenarioName, func(_ *testing.T) {
is.T().Parallel()
...
})
However this panics with
panic: testing: t.Parallel called multiple times [recovered]
panic: testing: t.Parallel called multiple times
How can one leverage parallelism with the specific package?
答案1
得分: 1
你正在对错误的 testing.T
实例调用 t.Parallel()
。
你正在使用以下方式启动多个子测试:
is.T().Run("Testing "+myOtherTestTable[i].scenarioName, func(_ *testing.T) {...}
但是,你没有将子测试标记为并行,而是将外部父测试标记为并行,对于每个启动的子测试都是如此:
is.T().Parallel() // 将外部测试标记为并行
相反,将子测试函数的 testing.T
参数绑定到一个变量,并在子测试上调用 Parallel
:
is.T().Run("Testing "+myOtherTestTable[i].scenarioName, func(t *testing.T) {
t.Parallel() // 这是子测试的 T 实例
// 测试代码
})
这将在父测试中将所有子测试标记为并行。如果你还想将父测试与包中的其他测试标记为并行,请在 TestSomethingElse
的开头调用 is.T().Parallel()
一次(不要在子测试中调用)。
有关子测试并行性的更多详细信息,请参阅:并行控制
英文:
You're calling t.Parallel()
on the wrong instance of testing.T
.
You're spinning up multiple subtests using:
is.T().Run("Testing "+myOtherTestTable[i].scenarioName, func(_ *testing.T) {...}
But instead of marking the subtest as parallel, you're marking the outer parent test as parallel for every subtest you start:
is.T().Parallel() // marks outer test as parallel
Instead, bind the subtest func's testing.T
param to a variable and call Parallel
on the subtest:
is.T().Run("Testing "+myOtherTestTable[i].scenarioName, func(t *testing.T) {
t.Parallel() // this is the subtest's T instance
// test code
})
This marks all subtests as parallel within the parent test. If you also want to mark the parent test as parallel with other tests in the package, call is.T().Parallel()
once at the beginning of TestSomethingElse
(not within the subtest)
For more details on parallelism of subtests, see: Control of Parallelism
答案2
得分: 0
请注意,目前的测试套件不是“线程安全”的,因此不支持并发。有些情况下,即使测试应该失败,但测试仍然成功通过。
请在此处查看当前状态以及报告的问题:https://github.com/stretchr/testify/issues/187
英文:
Please note that the testify suite is currently not "thread safe" and therefore does not support concurrency. There are cases in which tests pass successfully even though they should fail.
Please find the current status as well the reported issues here: https://github.com/stretchr/testify/issues/187
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论