如何在 “Go test” 中设置超时标志?

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

How to set the go timeout flag on "Go test"

问题

你好!以下是翻译好的内容:

执行命令 "go test -timeout 99999" 时出现了以下错误:

对于标志 -test.timeout,值 "99999" 是无效的:
时间:在持续时间 99999 中缺少单位。

这是一个 bug 吗?
我正在使用 go 版本 go1.3。

"help" 命令行界面也没有用。它说:“-test.timeout=0:如果为正数,则为所有测试设置一个总时间限制。”然而,如果你执行 go test -test.timeout 99999,你会得到相同的错误。

-test.timeout=0:如果为正数,则为所有测试设置一个总时间限制。

英文:
go test -timeout 99999

throws this non sense error

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

Is it a bug ?
I'm using
go version go1.3

The "help" cli is useless too. It says -test.timeout=0: if positive, sets an aggregate time limit for all tests. However if you do go test -test.timeout 99999 you get the same error

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

答案1

得分: 125

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

$ go test -timeout 300ms

$ go test -timeout 99999s

命令go

测试标志:

-timeout t

如果测试运行时间超过t,则会引发panic

flag

持续时间标志接受任何符合time.ParseDuration要求的输入。

time

函数ParseDuration

func ParseDuration(s string) (Duration, error)

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

命令 go

测试标志

包 flag

包 time

函数 ParseDuration

英文:

Use a valid time.ParseDuration input. For example,

$ go test -timeout 300ms

$ go test -timeout 99999s

> Command go
>
> Testing flags
>
> -timeout t
>
> If a test runs longer than t, panic.
>
> Package flag
>
> Duration flags accept any input valid for time.ParseDuration.
>
> Package time
>
> func ParseDuration
>
> func ParseDuration(s string) (Duration, error)
>
> ParseDuration parses a duration string. A duration string is a
> possibly signed sequence of decimal numbers, each with optional
> fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid
> time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".

答案2

得分: 23

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

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

假设您有一段代码,您怀疑某些goroutine会发生死锁,并且您希望确保测试失败。

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

func TestWithTimeOut(t *testing.T) {
    timeout := time.After(3 * time.Second)
    done := make(chan bool)
    go func() {
        // 进行测试
        time.Sleep(5 * time.Second)
        done <- true
    }()

    select {
    case <-timeout:
        t.Fatal("测试未能及时完成")
    case <-done:
    }
}
英文:

If you need this for just one test that you want to easily fail when it times out there is a neat way of just using timeout channels.

If I suspect a test will time out and I still want it to fail is to work with a timeout channel.

So imagine you have code where you suspect that some goroutines will deadlock and you want to make sure your test fails on that.

For that I run the actual test in a goroutine and the main goroutine then sits around waiting for either the done channel to finish or the timeout to finish.

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 &lt;- true
	}()

	select {
	case &lt;-timeout:
		t.Fatal(&quot;Test didn&#39;t finish in time&quot;)
	case &lt;-done:
	}
}

答案3

得分: 2

添加/更新Tigraine答案

> 如果你只需要为一个测试设置超时,以便在超时时轻松失败,有一种巧妙的方法可以使用超时通道。

实际上...提案/问题 48157 "cmd/go: 添加每个测试的超时"已被接受,并可能在<del>Go 1.18(2022年第一季度)</del>中发布。 (可能是Go 1.20,2022年第四季度)

> 测试对于整个二进制文件有一个总超时时间,但对于特定的测试用例没有超时时间。
>
> 通常,您希望将任何特定的测试用例的时间限制设置得比整个二进制文件的时间要短得多。
>
> 我建议将每个测试(函数)的超时概念添加到go命令的用户体验中,如下所示。
>
> 1. 每个测试都有一个独立的超时时间
给定测试的计时器仅在测试运行时递减。当测试在t.Parallel中被阻塞或在运行子测试的t.Run中被阻塞时,计时器不会递减。

> 2. 默认的每个测试用例超时时间为1分钟
如果显式指定了新的-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目标的执行设置超时时间
>
> 此更改在模糊测试和最小化期间,为每个fuzz目标的执行设置了10秒的超时时间。

2022年10月:CL 445597也引用了它。

英文:

To add/update to Tigraine's answer:

> If you need this for just one test that you want to easily fail when it times out there is a neat way of just using timeout channels.

Actually... proposal/issue 48157 "cmd/go: add per-test timeouts", accepted and possibly released with <del>Go 1.18 (Q1 2022)</del> will change that. (Maybe Go 1.20, Q4 2022)

> Tests have an overall timeout for the entire binary but no timeout for a specific test case.
You often want to limit any particular test case to a time much shorter than the overall binary.
>
> I propose to add the concept of per-test (function) timeouts to the go command user experience as follows.
>
> 1. Each test gets a per-test timeout.
The timer for a given test only ticks down when the test is running. It does not tick down when the test is blocked in t.Parallel, nor when it is blocked in t.Run running a subtest.
>
> 2. The default per-test case timeout is 1m (one minute).
If the new -testtimeout flag is specified explicitly, then that sets a different default.
If the -testtimeout flag is omitted but -timeout is specified explicitly, then that sets the default too. This way, if you have one really long test and use go test -timeout=30m, the per-case timeout doesn't kick in after 1 minute and kill it anyway.
>
> 3. There is a new testing.TB method SetTimeout(d time.Duration) that allows a test to set its own timeout.
Calling SetTimeout does not reset the timer. If a test runs for 30 seconds and then calls t.SetTimeout(1*time.Second), it gets killed for having timed out. A timeout set this way is inherited by subtests. (They each have their own timer.)
>
> When a test timeout happens, the whole process still gets killed. There's nothing we can really do about that. But the failure does say which test function timed out.

And so you now (Nov. 2021) have CL 363134, as an illustration:

> ## internal/fuzz: set timeout for each exec of fuzz target
>
> This change sets a timeout of 10 seconds on each execution of the fuzz target, both during fuzzing and during minimization.

Oct. 2022: CL 445597 also references it.

huangapple
  • 本文由 发表于 2014年7月24日 17:20:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/24929790.html
匿名

发表评论

匿名网友

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

确定