英文:
API Testing In Golang
问题
我知道Golang有一个testing package,可以用于运行单元测试。这对于内部调用Golang函数进行单元测试似乎效果很好,但似乎有些人试图将其适应于API测试。
鉴于像Node.js的Mocha测试框架和Chai断言库这样的自动化测试框架具有很大的灵活性,对于什么样的测试来说,使用Golang的testing package与其他工具相比更有意义呢?
谢谢。
英文:
I know that Golang has a testing package that allows for running unit tests. This seems to work well for internally calling Golang functions for unit tests but it seems that some people were trying to adapt it for API testing as well.
Given to the great flexibility of automated testing frameworks like Node.js' Mocha with the Chai assertion library, for what kind of tests does it make sense to use Golang's testing package vs. something else?
Thanks.
答案1
得分: 5
我同意@eduncan911的评论。更具体地说,您可以通过确保您的处理程序接受一个http.ResponseWriter
参数来设计具有测试意识的API,以及适当的请求。在那时,您将可以声明一个新的请求:
req, err := http.NewRequest("GET", "http://example.com", nil)
以及一个新的httptest
记录器:
recorder := httptest.NewRecorder()
然后将新的测试请求发送到您的处理程序:
yourHandler(recorder, req)
这样,您最终可以在记录器中检查错误等:
if recorder.Code != 200 {
//做一些操作
}
英文:
I agree with the comment by @eduncan911. More specifically you can design your API with testing in mind by making sure that your handlers accept an
http.ResponseWriter
as a parameter in addition to the appropriate request. At that point you will be set to declare a new request:
req, err := http.NewRequest("GET", "http://example.com", nil)
as well as a new httptest recorder:
recorder := httptest.NewRecorder()
and then issue the new test request to your handler:
yourHandler(recorder, req)
so that you can finally check for errors/etc. in the recorder:
if recorder.Code != 200 {
//do something
}
答案2
得分: 2
要进行虚拟请求,你需要首先初始化路由器,然后设置服务器,然后进行请求。
以下是具体步骤:
- 初始化路由器:router := mux.NewRouter()
- 设置测试服务器:testServer := httptest.NewServer(router)
- 创建请求:request, error := http.NewRequest("METHOD", "URL", Body)
- 创建响应记录器:resp := httptest.NewRecorder()
- 创建处理函数:handler := http.HandlerFunc(functionname)
我们的处理函数满足http.Handler接口,因此我们可以直接调用它们的ServeHTTP方法,并传入我们的请求和响应记录器。
handler.ServeHTTP(resp, req)
英文:
For making a dummy request, you have to first initialise the router and then set the server and after that make request.
Steps to be follow:
1. router := mux.NewRouter() //initialise the router
2. testServer := httptest.NewServer(router) //setup the testing server
3. request,error := http.NewRequest("METHOD","URL",Body)
4. // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
resp := httptest.NewRecorder()
5. handler := http.HandlerFunc(functionname)
// Our handlers satisfy http.Handler, so we can call their ServeHTTP method
// directly and pass in our Request and ResponseRecorder.
handler.ServeHTTP(resp, req)
答案3
得分: 0
我经常使用smartystreets goconvey和assertions包。虽然标准库提供了大部分你所需的功能,但我认为它缺少的是一些“便利性”功能。
goconvey包提供了一个漂亮的Web浏览器界面,支持热加载。每次更新代码后,它会重新运行测试。你还可以选择性地运行测试。所以我通常会在另一个控制台中运行它,并在编码时打开一个浏览器选项卡。它还可以方便地查看代码覆盖率。
组织和嵌套测试用例也变得非常容易,并且在Web浏览器中显示效果很好。
当然,assertions包只是提供了一些快捷方式。
我发现这样可以节省很多样板代码和时间。否则,我每个项目都需要编写相同的内容。
它还可以使你的测试更加一致。如果你有一套断言和工具库,你会首先使用其中的一个,而不是在另一个测试中构建一个自定义模式,然后偏离它。很容易出现混乱、难以阅读的测试。
还有其他一些包可以帮助测试API和HTTP请求。所以像其他人说的那样,你可以从头开始编写测试,或者使用一个处理样板代码的包。这样可以使你的测试代码更短、更清晰。
那么,“什么样的测试”?根据我的经验,几乎所有类型的测试都可以使用这些包。我一直从其他包中受益。不过要记住的重要一点是,所有这些都是建立在Golang已经提供的强大测试基础之上的。我之所以喜欢Golang而不是其他语言,其中一个原因就是它已经内置了大部分功能。我不是在添加缺失的功能,而是在为我的工作流程和偏好增加一些功能。然后,下一个运行我的包的人实际上可以自由选择只使用命令行界面,而不需要在浏览器中运行goconvey。所以偏好部分是可选的。这在其他地方并不常见。
英文:
I use smartystreets goconvey and assertions packages regularly. While the stdlib offers most everything you need, one thing I think it lacks is "quality of life" features.
The goconvey package will provide you with a nice web browser interface with hot reload. Everytime you update, it re-runs. You can also selectively choose what runs. So I typically open another console with it running which pops open a browser tab, as I code. It also makes looking at code coverage easy and convenient.
Organizing and nesting your test cases is also made easy and then renders nicely in your web browser.
Then of course the assertions package just provides you with some shortcuts.
What I've found is that this saves a lot of boilerplate and time. I'd be writing all the same stuff for each project otherwise.
It also makes your tests more consistent. If you have a library of assertions and tools, you will reach for one there first before building a custom pattern that you then deviate from in another test. It's not hard to end up with messy, hard to read tests.
There's other packages that help with testing APIs and HTTP requests as well. So like others said, you can do it from scratch, or you can use a package that takes care of the boilerplate. It could leave your tests shorter and cleaner.
So "what kind of tests?" All of them pretty much in my experience. I've always benefitted from other packages. Though the important thing to keep in mind is that all this is still built on top of the already awesome testing available in Golang. One reason why I like Golang over other languages is because it has most everything baked in already. I'm not bolting on something that's missing, I'm simply enhancing it for my work flow and preferences. Then the next person who comes along to run tests for my package is actually free to use just the CLI of they want. No need to run goconvey in their browser. So the preference parts stay preferential. This is not quite so common elsewhere.
答案4
得分: 0
这是我测试我的API的方法:https://github.com/cyruzin/feelthemovies/blob/master/internal/app/controllers/controller_test.go。我发现了一个有趣的函数叫做"func TestMain(m *testing.M) {}",它创建了一个用于测试的主程序。你可以使用它来设置你的依赖项和拆卸。
英文:
Here's how I tested my API: https://github.com/cyruzin/feelthemovies/blob/master/internal/app/controllers/controller_test.go. Digging around I found a interesting func called "func TestMain(m *testing.M) {}" that create a main routine for tests. You can use to setup your dependencies and teardown.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论