Testing APIs using RestAssure

API testing always strikes me as being the red headed stepchild in mobile development. Most of the apps we develop have a backend web service that someone else owns and the API’s specification is a moving target. Over the years APIs have been one of the major areas of frustration and costly rework. But it doesn’t have to be that way. There doesn’t need to be any finger pointing between the teams. The goal is to move the conversation from the subjective to the objective and remove the finger pointing. Thankfully there are plenty of tools out there that can help us with our goal. In the past we’ve used Postman for our API testing. This has worked well especially when used with Newman and Jenkins. Newman allows you to run Postman tests from the command line so it can be run in a Continuous Integration server such as Jenkins. If you want to find out more then check out this blog posting.

Lately we’ve been using RestAssure as the tests are easier for everyone to comprehend. This helps with out goal of making any communication issues much more obvious. RestAssure uses the gherkin format meaning it writes the tests in a given/when/then style , i.e. given the login API is called when I send the correct username and password then I should be authenticated. So if the mobile app fails when it sends the username and password but the API tests are still passing then we know the issue is on our end and if the test is failing then we know we need to get the API fixed or update the API call before we can continue.

Usage

In our simple example we’re going to take a look at an API call which is part of a public transit app which aggregates the routes and stop information for all the local transit companies here in the Metro Detroit area. There are 3 main APIs, one for the list of companies, one for the routes for that company and one for the routes. For example if we want to find the stops for SMART (company 1) for Route 125 going North on a weekday then I should get a result similar to what’s shown in Figure 1. The call we’re making here is http://someurl.com/companies/1/routes/125/Northbound/weekday/1/stops

 

Figure 1: Stops API Call

 

Using Postman I could check that the StopID of the METRO AIRPORT MCNAMARA TERMINAL is 22362 using the Postman code in Listing 1.

 var jsonData = JSON.parse(responseBody); tests["First stopID equals 22362"] = jsonData[0].stopID === "22362"; 

Listing 1: StopID

If I want to make sure the first stop name is METRO AIRPORT MCNAMARA TERMINAL then the Postman code we’d use is shown in Listing 2.

 tests["First stopName equals String METRO AIRPORT MCNAMARA TERMINAL"] = jsonData[0].stopName === "METRO AIRPORT MCNAMARA TERMINAL"; 

Listing 2: Stop Name

If QA were the only people using our code then that would be fine. A little cumbersome but fine. But if the APIs are a moving target then I want the cause of the errors to be quickly identified and we can do that by making them much easier to read using RestAssure’s given/when/then format.

 

We can rewrite the above test in RestAssure as follows, see Listing 3.

 given(). 
     pathParam("companyID", COMPANY_ID_SMART).
     pathParam("routeID", ROUTE_ID_125).
 when().
     get("/companies/{companyID}/routes/{routeID}/Northbound/weekday/1/stops").
 then().statusCode(200).
     and.body("stopID", Matchers.Item("22362").
     and.body("stopName", Matchers.Item("METRO AIRPORT MCNAMARA TERMINAL"); 

Listing 3: RestAssure Calls

Or in English we can say given the API is called for the Smart Bus Route 125 , when the stop id is 22632 then the name of the stop should be Metro Airport McNamara Terminal. This format makes it more likely that everyone is on the same page about what failed and who should be fixing it.

Continuous Integration

RestAssure can be part of the Android build or preferably it can also be run as a standalone Java project. I say preferably so I can run it from the command line and quickly add it to Jenkins, our Continuous Integration server as a Execute Shell command.

Install Maven and then run the command as follows, 

 mvn clean test

Example code 

One of the apps we use to teach new developers is a public transit app called ETA Detroit. The backend is a simple REST API with the following 4 basic calls

  • getCompanies
  • getStops
  • getRoutes
  • getPredictedTime

You can find sample tests for listing the transit companies, routes as well as stops and stop times in the repo https://github.com/riis/EtaDetroit-RESTAssuredTest

Conclusion

If you want to download RestAssure you can find it at https://github.com/rest-assured. So far we’ve found that it helps with our goals of making it easy to test APIs, easy to add to our build process in Jenkins. Finally the given/when/then format provides objective information on what has failed so we can quickly identify if it’s the mobile client or backend server team that needs to fix the code.

Related Posts