英文:
check whether test function will run in parallel
问题
如何检查一个 *testing.T
是否已设置为并行运行?
理想情况下,解决方案可能是:
func isParallelT(t *testing.T) bool {
// 返回某种方法来判断 t 是否调用了 t.Parallel()。
}
英文:
How can I check whether a *testing.T
has been set to run in parallel?
Ideally the solution might be:
func isParellelT(t *testing.T) bool {
// return some means to figure t has called t.Parallel().
}
答案1
得分: 4
testing.T
不提供此信息。您的测试不应依赖于它。如果您想要这样做,几乎肯定应该使用其他方法。
但是,可以使用反射访问私有数据,或者通过检查testing.T.SetEnv
是否引发恐慌来推导出私有数据:
package para
import (
"reflect"
"strings"
"testing"
)
func TestParallelTrue(t *testing.T) {
t.Parallel()
if !isParallel(t) {
t.Errorf("isParallel: got = false; want = true")
}
if !isParallel2(t) {
t.Errorf("isParallel2: got = false; want = true")
}
}
func TestParallelFalse(t *testing.T) {
if isParallel(t) {
t.Errorf("isParallel: got = true; want = false")
}
if isParallel2(t) {
t.Errorf("isParallel2: got = true; want = false")
}
}
// WARNING: This is terrible and should never be used.
// It will likely break on old or future versions of Go.
func isParallel(t *testing.T) (b bool) {
v := reflect.ValueOf(t).Elem()
// Check testing.T.isParallel first.
isPara := v.FieldByName("isParallel")
if isPara.IsValid() {
return isPara.Bool()
}
// Otherwise try testing.T.common.isParallel.
common := v.FieldByName("common")
if !common.IsValid() {
t.Fatal("isParallel: unsupported testing.T implementation")
}
isPara = common.FieldByName("isParallel")
if !isPara.IsValid() {
t.Fatal("isParallel: unsupported testing.T implementation")
}
return isPara.Bool()
}
// WARNING: This is terrible and should never be used.
// Requires Go1.17+.
func isParallel2(t *testing.T) (b bool) {
defer func() {
v := recover()
if v == nil {
return
}
if s, ok := v.(string); ok && strings.Contains(s, "parallel tests") {
b = true
return
}
panic(v)
}()
t.Setenv("_dummy", "value")
return false
}
英文:
testing.T
does not make this information available. Your tests should not depend on it. If you want to do this, you almost certainly should do something else instead.
However, it is possible to access the private data using reflection, or derive it by checking whether testing.T.SetEnv
panics 😈:
package para
import (
"reflect"
"strings"
"testing"
)
func TestParallelTrue(t *testing.T) {
t.Parallel()
if !isParallel(t) {
t.Errorf("isParallel: got = false; want = true")
}
if !isParallel2(t) {
t.Errorf("isParallel2: got = false; want = true")
}
}
func TestParallelFalse(t *testing.T) {
if isParallel(t) {
t.Errorf("isParallel: got = true; want = false")
}
if isParallel2(t) {
t.Errorf("isParallel2: got = true; want = false")
}
}
// WARNING: This is terrible and should never be used.
// It will likely break on old or future versions of Go.
func isParallel(t *testing.T) (b bool) {
v := reflect.ValueOf(t).Elem()
// Check testing.T.isParallel first.
isPara := v.FieldByName("isParallel")
if isPara.IsValid() {
return isPara.Bool()
}
// Otherwise try testing.T.common.isParallel.
common := v.FieldByName("common")
if !common.IsValid() {
t.Fatal("isParallel: unsupported testing.T implementation")
}
isPara = common.FieldByName("isParallel")
if !isPara.IsValid() {
t.Fatal("isParallel: unsupported testing.T implementation")
}
return isPara.Bool()
}
// WARNING: This is terrible and should never be used.
// Requires Go1.17+.
func isParallel2(t *testing.T) (b bool) {
defer func() {
v := recover()
if v == nil {
return
}
if s, ok := v.(string); ok && strings.Contains(s, "parallel tests") {
b = true
return
}
panic(v)
}()
t.Setenv("_dummy", "value")
return false
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论