我正在编写一个Web应用程序,它运行得很好。但是,在运行包的测试时,go test
命令只会挂起(它什么也不做,甚至不会终止)。
我有一个测试功能,它启动服务器:
func mkroutes(t *testing.T, f func()) {
handlerRegistry = handlerList([]handler{})
middlewareRegistry = []middleware{}
if testListener == nil {
_testListener, err := net.Listen("tcp", ":8081")
testListener = _testListener
if err != nil {
fmt.Printf("[Fail] could not start tcp server:\n%s\n", err)
}
}
f()
go func() {
if err := serve(testListener, nil); err != nil {
fmt.Printf("[Fail] the server failed to start:\n%s\n", err)
t.FailNow()
}
}()
}
如果我更改它侦听的端口,一切运行正常(但所有测试都失败了,因为它们无法连接到服务器)。这表明代码确实正在运行,但如果我在函数中记录某些内容,或者甚至在init
函数中,当端口正确时,它会再次中断。
强制go test
命令手动终止后,它会打印我记录的任何内容,然后退出。这让我相信在执行到达日志之前,其他东西在主线程上被阻塞,但这是不可能的,因为更改端口会产生影响。
该软件包没有任何init
函数,启动时运行的唯一代码是使用软件包var sessionStore = sessions.NewCookieStore([]byte("test-key"))
的{{1}}。当我正常运行程序时,这不会导致任何问题,并且我在包的源代码中看不到会导致它在测试中表现不同的任何内容。
这是导入标准库之外的唯一包。
我可以在包中提供任何其他代码,但我不知道什么是相关的。
答案 0 :(得分:2)
首先:请注意go test
将创建,编译和运行一个测试程序,该程序拦截每个测试的输出,因此在测试完成之前您将看不到测试的输出(此时打印输出)。
您的代码有两个问题:
如果您无法启动tcp服务器,则不会通知您,您只能在此处执行Printf并继续,就好像一切都很好。
你从不同的goroutine调用t.FailNow,而不是你的测试。你不能这样做。请参阅http://golang.org/pkg/testing/#T.FailNow
修复那些可能至少表明还有什么问题。另外:看一下net net / http如何进行测试。