Golang测试中的灯具

psb*_*its 6 python testing fixtures go reusability

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

ale*_*dwm 7

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

测试包维基:

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

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())
}
Run Code Online (Sandbox Code Playgroud)


Jam*_*mes 6

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

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

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)
}
Run Code Online (Sandbox Code Playgroud)

这将启动一个服务器net/http/httptest并返回它的 URL 以及一个充当“拆卸”的函数。这个函数被添加到 defer 堆栈中,因此无论测试用例如何退出,它总是被调用。

或者,*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)
}
Run Code Online (Sandbox Code Playgroud)