英文:
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
"。
英文:
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 <- true
}()
select {
case <-timeout:
t.Fatal("Test didn't finish in time")
case <-done:
}
}
答案3
得分: 2
> 如果你只需要为一个测试设置超时,以便在超时时轻松失败,有一种巧妙的方法可以使用超时通道。
实际上...提案/问题 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论