在Go语言中正确测试HTTP路由的方法

huangapple go评论93阅读模式
英文:

Proper testing of http routes in go

问题

我有5个端点,其中包含GET、POST和DELETE等方法,用于测试。我使用Go语言内置的测试包编写了测试用例。我担心我可能会漏掉一些我没有想到的情况。我已经在代码审查中发布了我的测试用例,但没有得到任何回应。我还遵循了这篇帖子Testing HTTP routes in golang。所有这些测试用例都是检查响应代码的。

问题是,我的大多数测试用例都遵循相似的模式,我在不同的格式中发布数据并检查响应代码。我强烈感觉我可能会漏掉一些在推送到生产环境时会破坏我的API的东西。我需要一些关于测试这些路由的见解,以便我可以有信心将API推送到生产环境。

main_test.go

func TestSigHandler(t *testing.T){

    test_cases := []string{"2021205"}  
    // GET Testing
    for _, method := range test_cases{
        usersUrl = fmt.Sprintf("%s/1/sig/id/%s", server.URL, method) //获取API端点的地址
        request, err := http.NewRequest("GET", usersUrl, nil)
        res, err := http.DefaultClient.Do(request)

        if err != nil {
            t.Error(err) //发送请求时出错
        }

        if res.StatusCode != 200  {
            t.Errorf("出错了:", res.StatusCode) //哦哦,这意味着我们的测试失败了
        }
    }

    // POST Testing
        sig := []byte( `{
        "raw": "a new sig"
    }`)
        usersUrl = fmt.Sprintf("%s/1/sig/id/2021205", server.URL) //获取API端点的地址
        request, err := http.NewRequest("POST", usersUrl, bytes.NewBuffer(sig))
        if err != nil{
            t.Error(err)
        }
        request.Header.Set("Content-Type", "application/json")
        res, err := http.DefaultClient.Do(request)

        if err != nil {
            t.Error(err) //发送请求时出错
        }

        if res.StatusCode != 200  {
            t.Errorf("出错了:", res.StatusCode) //哦哦,这意味着我们的测试失败了
        }

        // DELETE Testing

        sigs_delete_cases := []string{ "1000345"}
        for _, sig_to_be_deleted := range sigs_delete_cases{
            usersUrl = fmt.Sprintf("%s/1/sig/id/%s", server.URL, sig_to_be_deleted) //获取API端点的地址
            request, err := http.NewRequest("DELETE", usersUrl, nil)
            res, err := http.DefaultClient.Do(request)

            if err != nil {
                t.Error(err) //发送请求时出错
            }

            if res.StatusCode != 200  {
                t.Errorf("尝试删除保留的ID:", res.StatusCode) //哦哦,这意味着我们的测试失败了
            }
        }


}
英文:

I have 5 end points which have methods such as GET, POST, and DELETE to test. I wrote test cases using the go's in built testing package. I'm worried that I'm missing some cases which are not striking to my mind.I have posted in code review for my test case to be reviewed but I didn't get any response. I have also followed this post Testing HTTP routes in golang. All these test cases are checking for the response codes.

The problem is that, most of my test cases follow similar pattern where I post data in different formats and checking the response codes. I strongly feel like I'm missing something that will break my API when I push it to prod. I need some insight on testing these routes so that I can be confident to push the api to prod.

main_test.go

func TestSigHandler(t *testing.T){

    test_cases := []string{"2021205"}  
    // GET Testing
    for _, method := range test_cases{
        usersUrl = fmt.Sprintf("%s/1/sig/id/%s", server.URL, method) //Grab the address for the API endpoint
        request, err := http.NewRequest("GET", usersUrl, nil)
        res, err := http.DefaultClient.Do(request)

        if err != nil {
            t.Error(err) //Something is wrong while sending request
        }

        if res.StatusCode != 200  {
            t.Errorf("Something went wrong : ", res.StatusCode) //Uh-oh this means our test failed
        }
    }

    // POST Testing
        sig := []byte( `{
        "raw": "a new sig"
    }`)
        usersUrl = fmt.Sprintf("%s/1/sig/id/2021205", server.URL) //Grab the address for the API endpoint
        request, err := http.NewRequest("POST", usersUrl, bytes.NewBuffer(sig))
        if err != nil{
            t.Error(err)
        }
        request.Header.Set("Content-Type", "application/json")
        res, err := http.DefaultClient.Do(request)

        if err != nil {
            t.Error(err) //Something is wrong while sending request
        }

        if res.StatusCode != 200  {
            t.Errorf(" Something Went Wrong: ", res.StatusCode) //Uh-oh this means our test failed
        }

        // DELETE Testing

        sigs_delete_cases := []string{ "1000345"}
        for _, sig_to_be_deleted := range sigs_delete_cases{
            usersUrl = fmt.Sprintf("%s/1/sig/id/%s", server.URL, sig_to_be_deleted) //Grab the address for the API endpoint
            request, err := http.NewRequest("DELETE", usersUrl, nil)
            res, err := http.DefaultClient.Do(request)

            if err != nil {
                t.Error(err) //Something is wrong while sending request
            }

            if res.StatusCode != 200  {
                t.Errorf("Tried to delete a reserved Id : ", res.StatusCode) //Uh-oh this means our test failed
            }
        }


}

答案1

得分: 0

我喜欢这样做:

  1. 建立持续集成。如果你的项目是开源的,你可以使用像Travis CI这样的服务——它非常容易安装。这可以帮助你看到变更如何影响代码。

  2. 设置代码测试覆盖率。它可以让你看到哪些源代码行被测试覆盖,哪些没有被覆盖,以及可能出现的很多错误。当然,代码覆盖工具并不是万能的。如果一行代码被检查过,并不意味着它绝对没有问题,也不意味着它在其他输入下不会失败。但它对于维护良好的代码和查找错误非常有帮助。对于开源项目,你可以使用coveralls.io。有一个专门的goveralls插件可供使用。

  3. 为了解决上述问题,你可以使用所谓的模糊测试——使用随机输入进行探索性测试,以找到根本原因。有标准的https://golang.org/pkg/testing/quick/和非标准的包https://github.com/dvyukov/go-fuzz。

然后我对测试进行实验,包括正面和负面的测试。我尝试检查错误、超时和不正确的回复的情况。

对于我的测试,我通常使用http客户端和httptest包。

英文:

I like to do this way:

  1. Establish Continuous Integration. If your project is Open Source, you may use services like Travis CI - it has very easy installation. This helps you to see how changes affect code.

  2. Set code test coverage. It allows you to see what source code lines are covered with tests and what are not and where very possible bugs will emerge. Of course, code coverage tool is not a panacea. And if line was checked it doesn't mean it is absolutely ok, and it will not fail with other input. But it helps much to maintain good code and look for bugs. For open source you may use coveralls.io. There's a special goveralls plugin for it.

  3. To help the problem above you may use so-called Fuzzy testing - exploratory tests with random input to find a root cause. There're standard https://golang.org/pkg/testing/quick/ and non-standard packages https://github.com/dvyukov/go-fuzz.

Then I experiment with tests, they are both positive and negative. I try check situation with errors, timeouts, incorrect replies.

For my tests I've used as usual client http so httptest package.

huangapple
  • 本文由 发表于 2017年7月25日 02:51:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/45287975.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定