英文:
How to solve deadlock(waiting for singal from a failed test)
问题
我有两个goroutine,在测试期间分别是两个TestXxx函数。我使用一个条件变量来同步这些goroutine。然而,一旦其中一个测试失败,而另一个正在等待信号,就会出现死锁。此外,如果TestFunctionB失败,我希望TestFunctionA也失败。
我尝试了一些方法,例如:
var cond sync.Cond
func TestFunctionA(t *testing.T){
// ... 一些代码...
cond.Wait()
}
func TestFunctionB(t *testing.T){
// ... 一些代码...
t.Fail()
// ... 一些代码...
cond.Broadcast()
}
我尝试了以下方式:
var cond sync.Cond
var A_t *testing.T
func TestFunctionA(t *testing.T){
// ... 一些代码...
A_t = t
// ... 一些代码...
cond.Wait()
}
func TestFunctionB(t *testing.T){
// ... 一些代码...
t.Cleanup(func(){
if !A_t.Failed(){
A_t.Fail()
}
cond.Broadcast()
})
t.Fail()
// ... 一些代码...
cond.Broadcast()
}
但是,当FunctionB中没有错误时,A_t.Fail()仍然会触发。
我还在考虑使用context.Context(),但是我不知道如何在测试函数中使用它。
谢谢阅读我的问题!我欢迎任何评论或讨论!
英文:
I have two goroutines which are two TestXxx functions during the testing. I use a conditional variable to synchronize these goroutines. However, once one of them fails the test while the other one is waiting for the signal. Here comes a deadlock. Also, I want TestFunctionA to be failed if TestFunctionB is failed.
var cond sync.Cond
func TestFunctionA(t *testing.T){
// ... Some codes...
cond.Wait()
}
func TestFunctionB(t *testing.T){
// ... Some codes...
t.Fail()
// ... Some codes...
cond.Broadcast()
}
I've tried some ways, for example:
var cond sync.Cond
var A_t *testing.T
func TestFunctionA(t *testing.T){
// ... Some codes...
A_t = t
// ... Some codes...
cond.Wait()
}
func TestFunctionB(t *testing.T){
// ... Some codes...
t.Cleanup(func(){
if !A_t.Failed(){
A_t.Fail()
}
cond.Broadcast()
})
t.Fail()
// ... Some codes...
cond.Broadcast()
}
But the A_t.Fail() is still triggered when there is no error in FunctionB.
And I'm also considering using context.Context(). However, I have no idea how to run a Testfunction with a context.
Thank you for reading my question! I appreciate any comment or discussion!
答案1
得分: 0
一个测试不应该与另一个测试进行交互。但是,当使用__subtests__时,我们可以在测试用例之间共享任何内容。
以下是一个示例:
package main
import (
"errors"
"testing"
)
func TestFruits(t *testing.T) {
var err error
t.Run("test apple", getTestAppleFunc(&err))
t.Run("test banana", getTestBananaFunc(&err))
}
func handleError(t *testing.T, err *error) {
if err != nil && *err != nil {
t.Error(*err)
}
}
func getTestAppleFunc(err *error) func(*testing.T) {
return func(t *testing.T) {
handleError(t, err)
*err = errors.New("Apple failed")
}
}
func getTestBananaFunc(err *error) func(*testing.T) {
return func(t *testing.T) {
handleError(t, err)
}
}
- 在函数
getTestBananaFunc
和getTestAppleFunc
中,错误的指针被作为参数传递。 - 在上面的示例中,
getTestAppleFunc
首先被执行。 - 如果在
getTestAppleFunc
中分配了一个错误,就像上面的示例中所示,getTestBananaFunc
函数将失败。
英文:
A test should not interact with another test. But we can share anything between test cases when using subtests.
Here is an example:
package main
import (
"errors"
"testing"
)
func TestFruits(t *testing.T) {
var err error
t.Run("test apple", getTestAppleFunc(&err))
t.Run("test banana", getTestBananaFunc(&err))
}
func handleError(t *testing.T, err *error) {
if err != nil && *err != nil {
t.Error(*err)
}
}
func getTestAppleFunc(err *error) func(*testing.T) {
return func(t *testing.T) {
handleError(t, err)
*err = errors.New("Apple failed")
}
}
func getTestBananaFunc(err *error) func(*testing.T) {
return func(t *testing.T) {
handleError(t, err)
}
}
- In the functions
getTestBananaFunc
andgetTestAppleFunc
, the pointer of error is passed as an argument. - In the above example,
getTestAppleFunc
is executed first. - If an error is assigned in
getTestAppleFunc
, as shown in the above example, thegetTestBananaFunc
function will fail.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论