Golang测试中的灯具

时间:2016-01-20 00:59:21

标签: python testing go fixtures reusability

来自python世界,灯具非常有用(Fixtures为可重用状态/支持逻辑定义了Python合约,主要用于单元测试)。我想知道在Golang中是否有类似的支持,这可以让我使用一些预定义的装置来运行我的测试,例如设置服务器,将其拆除,每次运行测试时执行一些重复的任务?有人能指出我在Golang中做同样事情的一些例子吗?

2 个答案:

答案 0 :(得分:6)

如果您想使用标准的Go测试工具,您可以定义一个带有签名TestMain(m *testing.M)的函数,并将您的灯具代码放在那里。

来自testing package wiki

  

测试程序有时需要在测试之前或之后进行额外的设置或拆卸。有时还需要测试来控制在主线程上运行哪些代码。要支持这些和其他情况,如果测试文件包含函数:

     

func TestMain(m *testing.M)

     

然后生成的测试将调用TestMain(m)而不是直接运行测试。 TestMain在主goroutine中运行,可以执行任何设置,并且在调用m.Run时需要拆卸。然后应该使用m.Run的结果调用os.Exit。调用TestMain时,尚未运行flag.Parse。如果TestMain依赖于命令行标志,包括测试包的标志,它应该显式调用flag.Parse。

     

TestMain的一个简单实现是:

func TestMain(m *testing.M) {
    flag.Parse()
    os.Exit(m.Run())
}

答案 1 :(得分:1)

我知道这是一个古老的问题,但是仍然出现在搜索结果中,所以我想我可能给出一个答案。

您可以将代码隔离到帮助函数中,这些帮助函数将返回“拆解”函数以对其进行清理。这是启动服务器并在测试用例结束时关闭服务器的一种可能方法。

func setUpServer() (string, func()) {
    h := func(w http.ResponseWriter, r *http.Request) {
        code := http.StatusTeapot
        http.Error(w, http.StatusText(code), code)
    }

    ts := httptest.NewServer(http.HandlerFunc(h))
    return ts.URL, ts.Close
}

func TestWithServer(t *testing.T) {
    u, close := setUpServer()
    defer close()

    rsp, err := http.Get(u)
    assert.Nil(t, err)
    assert.Equal(t, http.StatusTeapot, rsp.StatusCode)
}

这将使用net/http/httptest启动服务器,并返回其URL以及充当“拆卸”的功能。此函数被添加到延迟堆栈中,因此无论测试用例如何退出,始终都会调用它。

(可选)如果您要进行更复杂的设置并且需要处理错误,则可以传入*testing.T。此示例显示设置函数返回*url.URL而不是URL格式的字符串,并且解析可能会返回错误。

func setUpServer(t *testing.T) (*url.URL, func()) {
    h := func(w http.ResponseWriter, r *http.Request) {
        code := http.StatusTeapot
        http.Error(w, http.StatusText(code), code)
    }

    ts := httptest.NewServer(http.HandlerFunc(h))
    u, err := url.Parse(ts.URL)
    assert.Nil(t, err)
    return u, ts.Close
}

func TestWithServer(t *testing.T) {
    u, close := setUpServer(t)
    defer close()

    u.Path = "/a/b/c/d"
    rsp, err := http.Get(u.String())
    assert.Nil(t, err)
    assert.Equal(t, http.StatusTeapot, rsp.StatusCode)
}