Test Assured!

REST is a very popular software architectural style that defines a set of constraints to be used for creating Web services. RESTful Web services provide interoperability between computer systems on the Internet. In microservice architectures the question of synchronous intercommunication between microservices has been answered by the implementation of REST. Synchronous means the client makes a request to the server and waits for its response. The thread will be blocked until it receives communication back. The most relevant protocol to implement synchronous communication is HTTP. HTTP can be implemented by REST or SOAP.

REST is based on the HTTP protocol which makes it recognisable and easy to implement. It uses verbs like GET, POST, PUT and DELETE. It is lightweight and language independent. For these reasons it has won the battle for modern application and microservice intercommunication, and is taking over the enterprise sector.

The following diagram shows the structure of a REST request:


It has headers which define the parameters of the transaction and depending on the verb (PUT, POST) it has a body. The Content-Type header defines the type of content the body contains (xml or json). The Accept header defines the type of content that is expected in the response. Basic authorization is generally Base64 encoded 'username:password'. Additional headers can be added to further define the transaction.


Methods of sending/receiving REST requests/responses

There are many methods of sending and receiving REST requests and responses to and from services. I will just look at 3 which I think all have a place in any engineer's library.

  • Curl
  • Postman
  • REST-Assured

Method 1 - Curl

Curl is a command line utility for making REST requests that enables you to set the verb, headers and body data. It is installed by default on Mac, on version 1803 or later of Windows 10, and on most linux versions. Where it is not installed by default it can be easily installed. It is very easy to use and can be encompassed in shell scripts with utilities like sed and awk or jq used to parse the response.

Here is an example of a curl post request:

    curl -i -X POST https://postman-echo.com/post  -H "Accept: application/json" -H "Authorization: Basic eFprSVdTbno6RkVIS0JuTmk=" -H "Content-Type: application/json; charset=UTF-8" -H "X-Header: 10e0d481-089b-4680-9ab6-be1d50c1c39e" -d @settings.json
                        

With the following being the contents of settings.json (Note you don't have to pass in a file. You can pass a string with the -d argument but in this example a file is used). The contents of settings.json were:

    {
        "id": "d00d220f-3d1c-465b-9e80-a5429c89ce22",
        "position": "079930c0-f98a-4d8a-8faa-ed00a5cdf457",
        "names": [
            {
                "name": "FCNmnCjp",
                "positions": [
                    "boss",
                    "manager",
                    "grunt"
                ],
                "city": "Oslo"
            },
            {
                "name": "shwMPxfK",
                "positions": [
                    "boss",
                    "manager",
                    "grunt"
                ],
                "city": "Rome"
            }
        ]
    }
                        

Here is it run and the response:


In the above:

  • the -i means Include the HTTP response headers in the output
  • the -X specifies that the verb to use (POST in this case)
  • the -H specifies a header and can be used multiple times for each header needed
  • the -d specifies the body of the request (for POST and PUT requests)

Curl is very handy to represent how to make calls in your documentation and its availability to use on most OSes without an install make it a very useful tool for REST testing


Method 2 - Postman

Postman is a lightweight GUI based tool that enables the user to quickly and easily create REST requests, send them and see the responses within the GUI frontend. From the Postman site:

  “Postman is a collaboration platform for API development. You can use Postman to design, build, and test APIs in conjunction with your teammates, and to support developer adoption.”
                        

Here is an example of a Postman request:


There is a dropdown to pick the HTTP verb you want, an address bar to enter the url to send the request to, tabs for headers, cookies and body. There is a button to send and the response comes back clearly. This makes REST requests very easy. Postman has to be downloaded and installed and it is also recommended that you create an account with Postman, or use a Google Account.

Postman is great for exploring new APIs and for debugging purposes where you are not sure how the request body should look. It is also very useful for ascertaining why a test suite is failing on a particular api call. Collections can be shared with less technical people to allow them to do some requests independently. In my experience Postman has basically taken over as the de-facto GUI interface to REST APIs.


Method 3 - REST-Assured

REST-Assured is a fluent framework to write REST tests in Java. Its fluency is very important as method chaining makes the requests readable and intuitive. Here is an example:

    given()
        .when()
            .filters(new RequestLoggingFilter(), new ResponseLoggingFilter())
            .headers(headers)
            .body(requestBody)
            .post(posturl)
        .then()
             .assertThat()
             .statusCode(SC_OK)
        .and()
             .contentType(ContentType.JSON)
        .and()
             .body("data.id", equalTo(requestBody.getId()));
                          

In the above:

  • headers is a map of string keys against object values
  • requestBody can be a file, an object, a byte array, or a string
  • filters used here log both the request and response. It is also possible to add a SwaggerValidationFilter to check that the request adheres to a swagger
  • and() is not needed and used to make the code more readable. Indeed, it is mostly not used
  • assertThat() is not needed and is made to make the code more readable. This too is mostly not used

The strength of REST-Assured is that it can be used as part of a test framework to test a system. If you want modern test automation, it has to be coded in a framework like this and should be tied into Continuous Integration/Continuous Delivery (CICD) build system.. Postman/Curl are useful tools but they will only get you so far due to the the amount of manual intervention, lack of re-usability and high cost of maintenance.

Tests written using REST-Assured are easy to read, write, maintain and extend. It is also very flexible with different test headers and bodies used in both positive and negative testing of endpoints.

For re-usability it is also possible to create a base specification for REST requests (comment headers etc for different tests) and just alter or enhance it for the individual tests.

REST-assured also allows you to put filters within the chain. A useful filter used is from Atlassian that uses the swagger to check the request and response.

Finally the body and headers can be built up from model classes and passed into the rest assured code so the user doesn't have to maintain ugly commented json files to use in the request body. This aids in the auto generation of test data for testing rest endpoints.


Conclusion

In conclusion, there are many handy and useful tools and methods for testing REST APIs and each has its use in certain situations. It is my opinion that testing within a scalable, portable framework tied into a CI/CD implementation is the way forward for all functional and end-to-end testing (not just for REST based services either!) and to that end I sincerely believe that to be test assured you need to be REST-Assured!