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

TestingGo

Testing Problem Overview


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

Testing Solutions


Solution 1 - Testing

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".

Solution 2 - Testing

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:
	}
}

Solution 3 - Testing

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 Go 1.18 (Q1 2022) will change that.

> 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 illulstration:

> ## 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionheyView Question on Stackoverflow
Solution 1 - TestingpeterSOView Answer on Stackoverflow
Solution 2 - TestingTigraineView Answer on Stackoverflow
Solution 3 - TestingVonCView Answer on Stackoverflow