【问题标题】:How to set the go timeout flag on "Go test"如何在“Go test”上设置 go timeout 标志
【发布时间】:2014-09-15 18:38:57
【问题描述】:
go test -timeout 99999

抛出这个无意义的错误

invalid value "99999" for flag -test.timeout: 
time: missing unit in duration 99999

这是一个错误吗? 我正在使用 去版本go1.3

“帮助”cli 也无用。它说-test.timeout=0: if positive, sets an aggregate time limit for all tests。但是如果你去 test -test.timeout 99999 你会得到同样的错误

 -test.timeout=0: if positive, sets an aggregate time limit for all tests

【问题讨论】:

  • "missing unit in duration 99999" 是怎么回事?

标签: testing go


【解决方案1】:
推荐的答案 Go Language

使用有效的time.ParseDuration 输入。例如,

$ go test -timeout 300ms

$ go test -timeout 99999s

Command go

Testing flags

-timeout t

如果测试运行时间超过tpanic

Package flag

持续时间标志接受任何对time.ParseDuration 有效的输入。

Package time

func ParseDuration

func ParseDuration(s string) (Duration, error)

ParseDuration 解析持续时间字符串。持续时间字符串是 可能有符号的十进制数序列,每个都有可选的 分数和单位后缀,例如“300ms”、“-1.5h”或“2h45m”。有效的 时间单位是“ns”、“us”(或“µs”)、“ms”、“s”、“m”、“h”。

【讨论】:

    【解决方案2】:

    如果您只需要一个测试并且希望在超时时轻松失败,那么有一种巧妙的方法就是使用超时通道。

    如果我怀疑测试会超时,但我仍然希望它失败,那就使用超时通道。

    因此,假设您有代码,您怀疑某些 goroutine 会死锁,并且您想确保测试失败。

    为此,我在 goroutine 中运行实际测试,然后主 goroutine 等待done 通道完成或timeout 完成。

    func TestWithTimeOut(t *testing.T) {
        timeout := time.After(3 * time.Second)
        done := make(chan bool)
        go func() {
            // do your testing
            time.Sleep(5 * time.Second)
            done <- true
        }()
    
        select {
        case <-timeout:
            t.Fatal("Test didn't finish in time")
        case <-done:
        }
    }
    

    【讨论】:

    • 优雅的解决方案。虽然我本来希望测试包本身有这样的功能
    【解决方案3】:

    添加/更新到Tigraineanswer

    如果您只需要一个测试并且希望在超时时轻松失败,那么有一种巧妙的方法就是使用超时通道。

    实际上...proposal/issue 48157 "cmd/go: add per-test timeouts",被接受并可能随 Go 1.18(2022 年第一季度)一起发布将改变这一点。

    测试对整个二进制文件有一个总体超时,但对特定测试用例没有超时。
    您通常希望将任何特定的测试用例限制在比整个二进制文件短得多的时间。

    我建议在 go 命令用户体验中加入 per-test (function) timeouts 的概念,如下所示。

    1. 每个测试都有一个每次测试超时
      给定测试的计时器仅在测试运行时计时。当测试在 t.Parallel 中被阻止时,它不会打勾,在 t.Run 中运行子测试时它也不会被阻止。

    2. 每个测试用例的默认超时时间为 1m(一分钟)
      如果明确指定了新的 -testtimeout 标志,则设置不同的默认值。
      如果-testtimeout 标志被省略但-timeout 被明确指定,那么这也设置了默认值。这样,如果您有一个非常长的测试并使用go test -timeout=30m,则每个案例的超时不会在 1 分钟后启动并且无论如何都会终止它。

    3. 有一个新的testing.TB 方法SetTimeout(d time.Duration) 允许测试设置自己的超时。
      调用SetTimeout 不会重置计时器。如果一个测试运行 30 秒然后调用t.SetTimeout(1*time.Second),它会因为超时而被杀死。以这种方式设置的超时由子测试继承。 (他们每个人都有自己的计时器。)

    当发生测试超时时,整个进程仍然会被杀死。对此我们真的无能为力。但失败确实说明了哪个测试功能超时。

    所以你现在(2021 年 11 月)有CL 363134,作为一个例子:

    internal/fuzz: 为 fuzz 目标的每个 exec 设置超时

    此更改将模糊目标的每次执行设置为 10 秒的超时,无论是在模糊测试期间还是在最小化期间​​。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-18
      • 1970-01-01
      • 2017-07-03
      • 1970-01-01
      相关资源
      最近更新 更多