How do you print in a Go test using the “testing” package?

后端 未结 6 1245
既然无缘
既然无缘 2020-12-12 12:07

I\'m running a test in Go with a statement to print something (i.e. for debugging of tests) but it\'s not printing anything.

func TestPrintSomething(t *testi         


        
6条回答
  •  无人及你
    2020-12-12 12:53

    t.Log() will not show up until after the test is complete, so if you're trying to debug a test that is hanging or performing badly it seems you need to use fmt.

    Yes: that was the case up to Go 1.13 (August 2019) included.

    And that was followed in golang.org issue 24929

    Consider the following (silly) automated tests:

    func TestFoo(t *testing.T) {
        t.Parallel()
    
      for i := 0; i < 15; i++ {
            t.Logf("%d", i)
            time.Sleep(3 * time.Second)
        }
    }
    
    func TestBar(t *testing.T) {
        t.Parallel()
    
      for i := 0; i < 15; i++ {
            t.Logf("%d", i)
            time.Sleep(2 * time.Second)
        }
    }
    
    func TestBaz(t *testing.T) {
        t.Parallel()
    
      for i := 0; i < 15; i++ {
            t.Logf("%d", i)
            time.Sleep(1 * time.Second)
        }
    }
    

    If I run go test -v, I get no log output until all of TestFoo is done, then no output until all of TestBar is done, and again no more output until all of TestBaz is done.
    This is fine if the tests are working, but if there is some sort of bug, there are a few cases where buffering log output is problematic:

    • When iterating locally, I want to be able to make a change, run my tests, see what's happening in the logs immediately to understand what's going on, hit CTRL+C to shut the test down early if necessary, make another change, re-run the tests, and so on.
      If TestFoo is slow (e.g., it's an integration test), I get no log output until the very end of the test. This significantly slows down iteration.
    • If TestFoo has a bug that causes it to hang and never complete, I'd get no log output whatsoever. In these cases, t.Log and t.Logf are of no use at all.
      This makes debugging very difficult.
    • Moreover, not only do I get no log output, but if the test hangs too long, either the Go test timeout kills the test after 10 minutes, or if I increase that timeout, many CI servers will also kill off tests if there is no log output after a certain amount of time (e.g., 10 minutes in CircleCI).
      So now my tests are killed and I have nothing in the logs to tell me what happened.

    But for (possibly) Go 1.14 (Q1 2020): CL 127120

    testing: stream log output in verbose mode

    The output now is:

    === RUN   TestFoo
    === PAUSE TestFoo
    === RUN   TestBar
    === PAUSE TestBar
    === RUN   TestGaz
    === PAUSE TestGaz
    === CONT  TestFoo
        TestFoo: main_test.go:14: hello from foo
    === CONT  TestGaz
    === CONT  TestBar
        TestGaz: main_test.go:38: hello from gaz
        TestBar: main_test.go:26: hello from bar
        TestFoo: main_test.go:14: hello from foo
        TestBar: main_test.go:26: hello from bar
        TestGaz: main_test.go:38: hello from gaz
        TestFoo: main_test.go:14: hello from foo
        TestGaz: main_test.go:38: hello from gaz
        TestBar: main_test.go:26: hello from bar
        TestFoo: main_test.go:14: hello from foo
        TestGaz: main_test.go:38: hello from gaz
        TestBar: main_test.go:26: hello from bar
        TestGaz: main_test.go:38: hello from gaz
        TestFoo: main_test.go:14: hello from foo
        TestBar: main_test.go:26: hello from bar
    --- PASS: TestFoo (1.00s)
    --- PASS: TestGaz (1.00s)
    --- PASS: TestBar (1.00s)
    PASS
    ok      dummy/streaming-test    1.022s
    

    It is indeed in Go 1.14, as Dave Cheney attests in "go test -v streaming output":

    In Go 1.14, go test -v will stream t.Log output as it happens, rather than hoarding it til the end of the test run.

    Under Go 1.14 the fmt.Println and t.Log lines are interleaved, rather than waiting for the test to complete, demonstrating that test output is streamed when go test -v is used.

    Advantage, according to Dave:

    This is a great quality of life improvement for integration style tests that often retry for long periods when the test is failing.
    Streaming t.Log output will help Gophers debug those test failures without having to wait until the entire test times out to receive their output.

提交回复
热议问题