0

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
            }
        }


}
Community
  • 1
  • 1
  • I think this is way too broad for SO. If you're only checking status codes, you're right to be worried, you should be checking response bodies and side-effects (e.g. if you post a new Widget, does it get correctly persisted to the database, or whatever your case may be). – Adrian Jul 24 '17 at 18:55
  • @Adrian I'm trying to post the data in actual format and wrong format. If it doesn't get posted I'm expecting a response code other than 200 and calling the error method. I edited the question with my test case. –  Jul 24 '17 at 18:58
  • No one can answer this for you. The possible space of requests you might receive is infinite. You could always try something like [Fuzz testing](https://en.wikipedia.org/wiki/Fuzzing) but in the end it's up to you to decide what is "enough" testing. – Adrian Jul 24 '17 at 19:00
  • @Adrian My api will definitely break if I do fuzzing. As of now, I'm doing this with the remaining end points : "(e.g. if you post a new Widget, does it get correctly persisted to the database, or whatever your case may be)." –  Jul 24 '17 at 19:03
  • 2
    Whoaa... define "break"? Invalid requests shouldn't "break" anything, they should return a "you gave me invalid input" type of error. If fuzzing would break your API, then it's not stable. – Adrian Jul 24 '17 at 19:07
  • @Adrian I got what you're saying. If a randomized input is given to the api, it should appropriately check the request body and send a proper response. –  Jul 24 '17 at 19:54
  • Possible duplicate of [How to test http calls in go using httptest](https://stackoverflow.com/questions/16154999/how-to-test-http-calls-in-go-using-httptest) – Jonathan Hall Jul 25 '17 at 09:29
  • @Flimzy I don't think I asked how to use httptest. I asked how to make my test cases to give more information about my API. –  Jul 25 '17 at 16:32
  • @Highsenberg: No, but httptest is the answer to your question. – Jonathan Hall Jul 25 '17 at 16:34
  • @Flimzy https://codereview.stackexchange.com/questions/171055/testing-http-routes-in-go I was using httptest to set up test server. –  Jul 25 '17 at 16:35

1 Answers1

0

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.

Eugene Lisitsky
  • 12,113
  • 5
  • 38
  • 59