How do you print in a Go test using the “testing” package?
我正在Go语言中运行一个带有打印内容的语句的测试(即用于测试的调试),但没有打印任何内容。
1 2 3 | func TestPrintSomething(t *testing.T) { fmt.Println("Say hi") } |
当我对此文件运行go test时,输出为:
1 | ok command-line-arguments 0.004s |
据我所知,真正使其打印的唯一方法是通过t.Error()进行打印,如下所示:
1 2 3 | func TestPrintSomethingAgain(t *testing.T) { t.Error("Say hi") } |
输出以下内容:
1 2 3 4 5 6 | Say hi --- FAIL: TestPrintSomethingAgain (0.00 seconds) foo_test.go:35: Say hi FAIL FAIL command-line-arguments 0.003s gom: exit status 1 |
我已经用Google搜索并浏览了手册,但没有找到任何东西。
结构
在此处查看更多详细信息:http://golang.org/pkg/testing/#pkg-index
如果像您的情况一样,要查看没有失败的测试日志,请提供
例如,
1 2 3 4 5 6 7 8 9 10 11 | package verbose import ( "fmt" "testing" ) func TestPrintSomething(t *testing.T) { fmt.Println("Say hi") t.Log("Say bye") } |
1 2 3 4 5 6 7 | go test -v === RUN TestPrintSomething Say hi --- PASS: TestPrintSomething (0.00 seconds) v_test.go:10: Say bye PASS ok so/v 0.002s |
Command go
Description of testing flags
1
2
3 -v
Verbose output: log all tests as they are run. Also print all
text from Log and Logf calls even if the test succeeds.
Package testing
func (*T) Log
1 func (c *T) Log(args ...interface{})Log formats its arguments using default formatting, analogous to
Println, and records the text in the error log. The text will be
printed only if the test fails or the -test.v flag is set.
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 usefmt .
是的:包括Go 1.13(2019年8月)就是这种情况。
之后在
Consider the following (silly) automated tests:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 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 ofTestFoo is done, then no output until all ofTestBar is done, and again no more output until all ofTestBaz 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.
IfTestFoo 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 andt.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.
但是对于(可能的)Go 1.14(Q1 2020):CL 127120
testing: stream log output in verbose mode
现在的输出是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | === 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 |
为了测试有时我会
1 | fmt.Fprintln(os.Stdout,"hello") |
另外,您可以打印到:
1 | fmt.Fprintln(os.Stderr,"hello) |
1 2 3 4 5 6 7 8 9 | // initZapLog is delegated to initialize a new 'log manager' func initZapLog() *zap.Logger { config := zap.NewDevelopmentConfig() config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder config.EncoderConfig.TimeKey ="timestamp" config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder logger, _ := config.Build() return logger } |
然后,每次,在每个测试中:
1 2 3 4 5 6 7 8 9 10 11 12 13 | func TestCreateDB(t *testing.T) { loggerMgr := initZapLog() // Make logger avaible everywhere zap.ReplaceGlobals(loggerMgr) defer loggerMgr.Sync() // flushes buffer, if any logger := loggerMgr.Sugar() logger.Debug("START") conf := initConf() /* Your test here if false { t.Fail() }*/ } |