4

我正在编写一个 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"))是使用该包的代码github.com/gorilla/sessions。当我正常运行程序时,这不会导致任何问题,而且我在包的源代码中看不到任何会导致它在测试中表现不同的东西。

这是标准库之外唯一导入的包。

我可以在包中提供任何其他代码,但我不知道什么是相关的。

4

1 回答 1

2

首先:请注意,这go test将创建、编译和运行一个测试程序,该程序会拦截每个测试的输出,因此在测试完成之前您将看不到测试的输出(此时打印输出)。

您的代码有两个问题:

  1. 如果无法启动 tcp 服务器 t 不通知,您只需在此处执行 Printf 并继续,就好像一切都很好。

  2. 你从一个不同于你的测试运行的 goroutine 调用 t.FailNow。你不能这样做。请参阅http://golang.org/pkg/testing/#T.FailNow

解决这些问题至少可以显示还有什么问题。另外:看看 package net/http 是如何测试的。

于 2013-07-01T07:39:14.233 回答