我在Go中运行一个测试,用语句打印一些东西(即用于调试测试),但它没有打印任何东西。

func TestPrintSomething(t *testing.T) {
    fmt.Println("Say hi")
}

当我在这个文件上运行go test时,输出如下:

ok      command-line-arguments  0.004s

据我所知,真正让它打印的唯一方法是通过t.Error()打印它,就像这样:

func TestPrintSomethingAgain(t *testing.T) {
    t.Error("Say hi")
}

输出如下:

Say hi
--- FAIL: TestPrintSomethingAgain (0.00 seconds)
    foo_test.go:35: Say hi
FAIL
FAIL    command-line-arguments  0.003s
gom:  exit status 1

我用谷歌搜索过手册,但什么也没找到。


当前回答

警告:这里的答案不适用于同时测试多个包。

来自@VonC和@voidlogic的答案非常棒,但我想引起以下线程的注意,以防有人正在运行go test -v ./…: https://github.com/golang/go/issues/46959

问题在于与从多个包运行测试相关的实现细微差别/困难。

例如:执行go test -v -count=1 -run TestOnlyOneInstanceOfThisTestExists ./multiple/packages/exist/below/…仅在测试完成后打印日志。

但是,执行go test -v -count=1 -run TestOnlyOneInstanceOfThisTestExists ./this/path/points/to/one/package/only/…将按预期输出流。

其他回答

结构测试。T和测试。B都有. log和. logf方法,听起来就是你要找的。log和. logf方法类似于fmt。打印和fmt。Printf分别。

更多详情请访问:http://golang.org/pkg/testing/#pkg-index

fmt。X打印语句在测试中确实可以工作,但是您会发现它们的输出可能不在您期望找到它的屏幕上,因此,您应该在测试中使用日志方法。

如果像您的情况一样,希望查看未失败的测试的日志,则必须提供go test -v标志(v表示冗长)。关于测试标志的更多细节可以在这里找到:https://golang.org/cmd/go/#hdr-Testing_flags

例如,

package verbose

import (
    "fmt"
    "testing"
)

func TestPrintSomething(t *testing.T) {
    fmt.Println("Say hi")
    t.Log("Say bye")
}

go test -v
=== RUN TestPrintSomething
Say hi
--- PASS: TestPrintSomething (0.00 seconds)
    v_test.go:10: Say bye
PASS
ok      so/v    0.002s

命令去 测试标志的描述 - v 详细输出:在运行所有测试时记录它们。同时打印所有 即使测试成功,也会调用Log和Logf中的文本。


包测试 func (*T) Log func (c *T) Log(参数…接口{}) Log使用默认格式(类似于Println)格式化其参数,并在错误日志中记录文本。对于测试,只有在测试失败或-test时才会打印文本。设置V标志。对于基准测试,文本总是打印出来,以避免性能依赖于-test的值。v标志。

警告:这里的答案不适用于同时测试多个包。

来自@VonC和@voidlogic的答案非常棒,但我想引起以下线程的注意,以防有人正在运行go test -v ./…: https://github.com/golang/go/issues/46959

问题在于与从多个包运行测试相关的实现细微差别/困难。

例如:执行go test -v -count=1 -run TestOnlyOneInstanceOfThisTestExists ./multiple/packages/exist/below/…仅在测试完成后打印日志。

但是,执行go test -v -count=1 -run TestOnlyOneInstanceOfThisTestExists ./this/path/points/to/one/package/only/…将按预期输出流。

* _t。go文件和其他文件一样是一个go源文件,如果你需要转储复杂的数据结构,你可以每次初始化一个新的日志记录器,这里有一个例子:

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

然后,每次,在每次测试中:

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()
    }*/
}

t.Log()直到测试完成后才会显示,因此如果您试图调试挂起或执行不良的测试,似乎需要使用fmt。

是的:包括Go 1.13(2019年8月)之前都是这样。

这是在golang.org的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.

但(可能)Go 1.14(2020年Q1): CL 127120

测试:流日志输出在详细模式

现在的输出是:

=== RUN   TestFoo
=== PAUSE TestFoo
=== RUN   TestBar
=== PAUSE TestBar
=== RUN   TestBaz
=== PAUSE TestBaz
=== CONT  TestFoo
=== CONT  TestBaz
    main_test.go:30: 0
=== CONT  TestFoo
    main_test.go:12: 0
=== CONT  TestBar
    main_test.go:21: 0
=== CONT  TestBaz
    main_test.go:30: 1
    main_test.go:30: 2
=== CONT  TestBar
    main_test.go:21: 1
=== CONT  TestFoo
    main_test.go:12: 1
=== CONT  TestBaz
    main_test.go:30: 3
    main_test.go:30: 4
=== CONT  TestBar
    main_test.go:21: 2
=== CONT  TestBaz
    main_test.go:30: 5
=== CONT  TestFoo
    main_test.go:12: 2
=== CONT  TestBar
    main_test.go:21: 3
=== CONT  TestBaz
    main_test.go:30: 6
    main_test.go:30: 7
=== CONT  TestBar
    main_test.go:21: 4
=== CONT  TestBaz
    main_test.go:30: 8
=== CONT  TestFoo
    main_test.go:12: 3
=== CONT  TestBaz
    main_test.go:30: 9
=== CONT  TestBar
    main_test.go:21: 5
=== CONT  TestBaz
    main_test.go:30: 10
    main_test.go:30: 11
=== CONT  TestFoo
    main_test.go:12: 4
=== CONT  TestBar
    main_test.go:21: 6
=== CONT  TestBaz
    main_test.go:30: 12
    main_test.go:30: 13
=== CONT  TestBar
    main_test.go:21: 7
=== CONT  TestBaz
    main_test.go:30: 14
=== CONT  TestFoo
    main_test.go:12: 5
--- PASS: TestBaz (15.01s)
=== CONT  TestBar
    main_test.go:21: 8
=== CONT  TestFoo
    main_test.go:12: 6
=== CONT  TestBar
    main_test.go:21: 9
    main_test.go:21: 10
=== CONT  TestFoo
    main_test.go:12: 7
=== CONT  TestBar
    main_test.go:21: 11
=== CONT  TestFoo
    main_test.go:12: 8
=== CONT  TestBar
    main_test.go:21: 12
    main_test.go:21: 13
=== CONT  TestFoo
    main_test.go:12: 9
=== CONT  TestBar
    main_test.go:21: 14
=== CONT  TestFoo
    main_test.go:12: 10
--- PASS: TestBar (30.01s)
=== CONT  TestFoo
    main_test.go:12: 11
    main_test.go:12: 12
    main_test.go:12: 13
    main_test.go:12: 14
--- PASS: TestFoo (45.02s)
PASS
ok      command-line-arguments  45.022s

它确实在Go 1.14中,正如Dave Cheney在“Go test -v流输出”中所证明的那样:

在Go 1.14中,Go test -v将在t.Log输出发生时进行流处理,而不是将其保存到测试运行结束。

下Go 1.14的fmt。Println和t.Log行是交错的,而不是等待测试完成,这表明当使用go test -v时,测试输出是流的。

根据戴夫的说法,优点是:

对于在测试失败时经常长时间重试的集成风格测试来说,这是一个很大的生活质量改进。 流化t.Log输出将帮助Gophers调试这些测试失败,而不必等到整个测试超时才能接收它们的输出。