检查测试函数是否会并行运行。

huangapple go评论71阅读模式
英文:

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
}

huangapple
  • 本文由 发表于 2023年1月6日 08:48:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75025877.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定