Rest API Automation using Spring, JsonSchema2Pojo, JsonDiff, and Unitils

Before automating any Rest API call, It is always nice to try the call manually, either in Postman in Chrome or via curl, just to see whether or not the call is working as expected. Then automate it following:

Process of Rest API Automation
  • Model response into a POJO
  • Serialize the response object into a file as the expected result for later verification
  • Generate the Rest Request programmatically, and serialize the actual response into POJO object
  • Verify response using recursive assertion tools

1. Model response into a POJO
We need a way to model response(Being JSON or xml) into an Plain Old Java Object(POJO) as a container to hold our response data. We can manually write the class ourselves, but why should we if there are good tools like this for automatic generation of POJO: Jsonschema2pojo

Jsonschema2pojo can generate POJO from Json String, or JSON schema. This is how you do it using JSON string:

Copy your sample json response or json schema and drop it here, and then choose corresponding source type

Figure 1: Jsonschema2pojo:Copy Json String into the box

Then scroll down and click on Preview button, and it will create POJO class for you automatically

Figure 2: Jsonschema2pojo:Generate POJO

Then you can paste this code into your POJO package of your project. You will have to tweak the code a little like modifying package name, change the class name ‘Example’ to a more proper one etc.

In the next step when we generate request and send it over to REST server, we will serialize the Response into POJO object.

2. Serialize the response object into a file as the expected result for later verification
When serialize the response, we need to take into consideration on what fields that are expected to have different value every time we make a request using identical parameters. Time Stamp related field or ID could be different every time you make the same request. These fields need special treatment.

First, find out the fields that will be different every time you make the same request
1. Send the same request to rest server twice in postman, and save both response body

2. find out what fields are going to change legitimately by comparing json response using Json Diff Tools:
JSON Diff View (Firefox)
JSON Diff

Then handle those ever-changing fields when serializing the object:
Option 1: Use transient keyword
use the transient keyword for the corresponding POJO variables. The values of the transient fields will not be serialized. But we cannot ignore those fields completely since some of them are mandatory, and an important part of the tests is to guarantee that they are not nulls.

Option 2: Apply constraints to POJO variables with annotations
Serialize those fields as normal, but decorate mandatory POJO class variables with annotations of interest like: @NotNull,@Size(min=.., max=…), @Min(…), and @Max(…), then validate the response using javax.validation.Validator from Hibernate Validator library (http://hibernate.org/validator).

3. Generate the Rest Request programmatically, and serialize the response into POJO object
I use JAVA Spring Framework to generate request. So do include this in your pom.xml:

<!– https://mvnrepository.com/artifact/org.springframework/spring-web –<
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>

Example code to generate POST request:

public static void createPostRequest( ) throws Exception {
String requestJson = “{\”respond_with\”:{\”user_id\”:\”94513611\”,\”config\”:{\”config_time\”:1452277446}},\”attributes\”:[{\”user_id\”:\”94513611\”,\”custom\”:{\”Most Recent Web Version\”:\”7.20.0\”},\”email\”:\”XXXX@gmail.com\”}],\”api_key\”:\”73f8cae6-7de9-48ef-adc5-fcbd335f6d61\”,\”time\”:1481396076,\”sdk_version\”:\”1.6.4\”,\”app_version\”:\”7.20.0\”,\”device_id\”:\”de872546-ef74-6f10-9e83-211cf8c8636e\”}”;

RestTemplate restTemplate = new RestTemplate();

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

//create POST Request body
HttpEntity entity = new HttpEntity(requestJson,headers);

//Get Json response and serialize it into POJO ‘ResonseContent’.
ResponseContent response = restTemplate.postForObject(SERVICE_URI_HOME, entity, ResponseContent.class);
}

You can scroll to the end of this page to see sample code for Serialization(Dump POJO object into a file) and De-serialization(Create POJO object from a file).

4. Verify response using recursive assertion tools
Rest Automation needs to check at least the status code,the header information, and most of all, response content.
We can use Junit or testNg assert to check status code and specific header field, but for JSON/xml response which might contain other objects, we need a tool that can recursively check all object fields. We can use this tool for recursive assertion:

Unitils assertReflectionEquals(expectedObject, actualObject) loops over all fields in both objects and compares their values using reflection. If a field value itself is an object, it will be recursively compared field by field. Reflection assert automatically excludes transient variables from comparison. You can also ignore non-transient values by specifying ReflectionComparatorMode.IGNORE_DEFAULTS mode in the assertReflectionEquals(). This mode excludes all fields that designated as nulls in the expected object.

A sample usage:

import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals;
[….. ]
void verifyResult(Example actual, Example expected){
assertReflectionEquals(“response is different from expected.”, actual , expected);
}

Shazamcrest is a similar recursive assertion tool. I will skip details here.

Sample code of serialization and de-serialization
Serialization:Dump object into a file:

public String serialize(Object obj, String fileName)
{
try {
File file = new File(fileName + “.ser”);
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
oos.close();
fos.close();
}catch(Exception e)
{ e.printStackTrace();
}finally {
}
return fileName + “.ser”;
}

De-serialization: Create object from a file

public MyResponse deserialization(String serFile){
MyResponse responseObject= new MyResponse ();
try {
FileInputStream fis = new FileInputStream(serFile);
ObjectInputStream ois = new ObjectInputStream(fis);
si = (MyResponse )ois.readObject();
fis.close();
ois.close();
} catch (Exception e){
e.printStackTrace();
}finally {
}
return si;
}

One thought on “Rest API Automation using Spring, JsonSchema2Pojo, JsonDiff, and Unitils

Leave a Reply

Your email address will not be published. Required fields are marked *