我正在Go中运行一个带有声明的测试来打印某些内容(即用于调试测试),但它不会打印任何内容。
func TestPrintSomething(t *testing.T) {
fmt.Println("Say hi")
}
当我对此文件运行测试时,这是输出:
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
我用Google搜索并查看了手册,但没有找到任何内容。
答案 0 :(得分:99)
例如,
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 Verbose output: log all tests as they are run. Also print all text from Log and Logf calls even if the test succeeds.
func (c *T) Log(args ...interface{})
Log使用默认格式设置其参数的格式,类似于 Println,并将文本记录在错误日志中。文字将是 仅在测试失败或设置了-test.v标志时打印。
答案 1 :(得分:96)
结构testing.T
和testing.B
都有一个.Log
和.Logf
方法,听起来就像你要找的那样。 .Log
和.Logf
分别与fmt.Print
和fmt.Printf
相似。
在此处查看更多详情:http://golang.org/pkg/testing/#pkg-index
fmt.X
打印语句执行在测试中工作,但您会发现他们的输出可能不在您希望找到它的屏幕上,因此,您应该使用日志记录方法的原因在testing
。
如果您希望查看未失败的测试的日志,则可以提供go test
-v
标记(v表示详细程度)。有关测试标志的更多详细信息,请访问:http://golang.org/cmd/go/#hdr-Description_of_testing_flags
答案 2 :(得分:4)
t.Log()
直到测试完成后才会显示,因此,如果您要调试挂起或性能不佳的测试,看来您需要使用fmt
。
是的:包括Go 1.13(2019年8月)就是这种情况。
请考虑以下(愚蠢的)自动化测试:
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) } }
如果我运行
go test -v
,在所有TestFoo
完成之前我没有日志输出,然后在所有TestBar
完成之前没有任何输出,并且在所有TestBaz
完成之前,不再输出任何内容。
如果测试正常,这很好,但是如果存在某种错误,则在某些情况下,缓冲日志输出会出现问题:
- 在本地进行迭代时,我希望能够进行更改,运行测试,立即查看日志中的内容以了解发生了什么,如有必要,请按CTRL + C提前关闭测试,然后进行其他更改,然后重新运行测试,依此类推。
如果TestFoo
较慢(例如,这是一个集成测试),那么直到测试结束我都不会收到日志输出。这会大大减慢迭代速度。- 如果
TestFoo
有一个导致其挂起并且永远无法完成的错误,那么我将不会获得任何日志输出。在这些情况下,t.Log
和t.Logf
根本没有用。
这使得调试非常困难。- 此外,不仅没有日志输出,而且如果测试挂起时间太长,Go测试超时会在10分钟后终止测试,或者如果我增加该超时时间,那么许多CI服务器也会在以下情况下终止测试:一定时间(例如CircleCI中的10分钟)后没有日志输出。
所以现在我的测试被杀死了,日志中什么也没有告诉我发生了什么。
但是(可能)执行1.14(2020年第一季度):CL 127120
测试:以详细模式输出流日志
现在的输出是:
=== 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
答案 3 :(得分:3)
t.Log
和t.Logf
确实会在您的测试中打印出来,但是由于它与测试在同一行上打印,因此经常会被漏掉。我要做的是以使它们脱颖而出的方式记录它们,即
t.Run("FindIntercomUserAndReturnID should find an intercom user", func(t *testing.T) {
id, err := ic.FindIntercomUserAndReturnID("test3@test.com")
assert.Nil(t, err)
assert.NotNil(t, id)
t.Logf("\n\nid: %v\n\n", *id)
})
将其打印到终端,
=== RUN TestIntercom
=== RUN TestIntercom/FindIntercomUserAndReturnID_should_find_an_intercom_user
TestIntercom/FindIntercomUserAndReturnID_should_find_an_intercom_user: intercom_test.go:34:
id: 5ea8caed05a4862c0d712008
--- PASS: TestIntercom (1.45s)
--- PASS: TestIntercom/FindIntercomUserAndReturnID_should_find_an_intercom_user (1.45s)
PASS
ok github.com/RuNpiXelruN/third-party-delete-service 1.470s
答案 4 :(得分:0)
有时候我会做测试
fmt.Fprintln(os.Stdout, "hello")
答案 5 :(得分:0)
*_test.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()
}*/
}
答案 6 :(得分:-1)
如果您使用 testing.M
和相关的设置/拆卸; -v
在这里也有效。
package g
import (
"os"
"fmt"
"testing"
)
func TestSomething(t *testing.T) {
t.Skip("later")
}
func setup() {
fmt.Println("setting up")
}
func teardown() {
fmt.Println("tearing down")
}
func TestMain(m *testing.M) {
setup()
result := m.Run()
teardown()
os.Exit(result)
}
$ go test -v g_test.go
setting up
=== RUN TestSomething
g_test.go:10: later
--- SKIP: TestSomething (0.00s)
PASS
tearing down
ok command-line-arguments 0.002s