What is JSON Schema?

API testing is a critical aspect of software development that ensures the reliability and performance of your application. Among the various testing techniques, JSON schema validation is essential for verifying that the JSON responses conform to a predefined structure. In this article, we will explore how to perform JSON schema validation in API testing using Rest-Assured, a popular Java library for testing RESTful web services.

JSON Schema is a powerful tool for validating the structure of JSON data. It provides a contract for what a JSON document should look like, including the expected properties, types, and other constraints. By defining a JSON schema, you ensure that your API responses are consistent and meet the required specifications.

Why Use Rest-Assured for JSON Schema Validation?

Rest-Assured is a flexible and easy-to-use Java library designed specifically for testing REST APIs. It simplifies the process of making HTTP requests and verifying responses. With Rest-Assured, you can easily integrate JSON schema validation into your API tests, ensuring that your endpoints return the expected data structure.

Setting Up Rest-Assured

Before we dive into JSON schema validation, let’s set up Rest-Assured in your project. You will need to add the necessary dependencies to your pom.xml file if you’re using Maven:

xml

<dependencies>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>4.3.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>4.3.3</version>
<scope>test</scope>
</dependency>
</dependencies>

For Gradle, you can add the following to your build.gradle file:

gradle

testImplementation 'io.rest-assured:rest-assured:4.3.3'
testImplementation 'io.rest-assured:json-schema-validator:4.3.3'

Writing a Basic API Test with Rest-Assured

Let’s start with a simple example of making an API request and validating the response status code using Rest-Assured.

java

import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class BasicApiTest {@Test
public void testGetEndpoint() {
RestAssured.baseURI = “https://jsonplaceholder.typicode.com”;given().
when().
get(“/posts/1”).
then().
assertThat().
statusCode(200).
body(“userId”, equalTo(1)).
body(“id”, equalTo(1)).
body(“title”, notNullValue()).
body(“body”, notNullValue());
}
}

In this example, we perform a GET request to https://jsonplaceholder.typicode.com/posts/1 and validate the status code and response body.

Creating a JSON Schema

To validate the JSON response, we need to create a JSON schema. You can use online tools like JSON Schema Generator to generate a schema from a sample JSON response. Here is an example schema for the response from the above endpoint:

json

{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"userId": {
"type": "integer"
},
"id": {
"type": "integer"
},
"title": {
"type": "string"
},
"body": {
"type": "string"
}
},
"required": ["userId", "id", "title", "body"]
}

Save this schema in a file named postSchema.json.

Performing JSON Schema Validation

With the JSON schema ready, we can now validate the API response using Rest-Assured. Here’s how you can do it:

java

import io.restassured.RestAssured;
import io.restassured.module.jsv.JsonSchemaValidator;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class JsonSchemaValidationTest {@Test
public void testGetEndpointWithSchemaValidation() {
RestAssured.baseURI = “https://jsonplaceholder.typicode.com”;given().
when().
get(“/posts/1”).
then().
assertThat().
statusCode(200).
body(JsonSchemaValidator.matchesJsonSchemaInClasspath(“postSchema.json”));
}
}

In this example, we use JsonSchemaValidator.matchesJsonSchemaInClasspath("postSchema.json") to validate the response against the JSON schema. Make sure the postSchema.json file is placed in the src/test/resources directory.

Advanced JSON Schema Validation

JSON schema validation can be more complex, involving arrays and nested objects. Let’s consider an example where the response contains an array of objects. Here’s a sample response:

json

[
{
"userId": 1,
"id": 1,
"title": "Sample Title",
"body": "Sample Body"
},
{
"userId": 1,
"id": 2,
"title": "Another Title",
"body": "Another Body"
}
]

The corresponding JSON schema might look like this:

json

{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"properties": {
"userId": {
"type": "integer"
},
"id": {
"type": "integer"
},
"title": {
"type": "string"
},
"body": {
"type": "string"
}
},
"required": ["userId", "id", "title", "body"]
}
}

Save this schema in a file named postsSchema.json.

Now, let’s write a test to validate the response against this schema:

java

import io.restassured.RestAssured;
import io.restassured.module.jsv.JsonSchemaValidator;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class ArrayJsonSchemaValidationTest {@Test
public void testGetArrayEndpointWithSchemaValidation() {
RestAssured.baseURI = “https://jsonplaceholder.typicode.com”;given().
when().
get(“/posts”).
then().
assertThat().
statusCode(200).
body(JsonSchemaValidator.matchesJsonSchemaInClasspath(“postsSchema.json”));
}
}

This test validates that the response is an array of objects, each conforming to the specified schema.

Handling Complex Nested JSON Structures

For more complex scenarios involving nested JSON structures, the process remains similar. Consider the following JSON response:

json

{
"userId": 1,
"id": 1,
"title": "Sample Title",
"body": "Sample Body",
"comments": [
{
"commentId": 1,
"comment": "Sample Comment"
},
{
"commentId": 2,
"comment": "Another Comment"
}
]
}

The JSON schema for this response might look like this:

json

{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"userId": {
"type": "integer"
},
"id": {
"type": "integer"
},
"title": {
"type": "string"
},
"body": {
"type": "string"
},
"comments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"commentId": {
"type": "integer"
},
"comment": {
"type": "string"
}
},
"required": ["commentId", "comment"]
}
}
},
"required": ["userId", "id", "title", "body", "comments"]
}

Save this schema in a file named postWithCommentsSchema.json.

And the corresponding test might look like this:

java

import io.restassured.RestAssured;
import io.restassured.module.jsv.JsonSchemaValidator;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class NestedJsonSchemaValidationTest {@Test
public void testGetNestedEndpointWithSchemaValidation() {
RestAssured.baseURI = “https://jsonplaceholder.typicode.com”;given().
when().
get(“/posts/1/comments”).
then().
assertThat().
statusCode(200).
body(JsonSchemaValidator.matchesJsonSchemaInClasspath(“postWithCommentsSchema.json”));
}
}

This test ensures that the nested JSON structure is validated correctly against the defined schema.

Best Practices for JSON Schema Validation

  1. Keep Schemas Updated: Ensure your JSON schemas are always in sync with your API specifications.
  2. Modular Schemas: Break down large schemas into modular parts that can be reused across different endpoints.
  3. Automation: Integrate schema validation tests into your CI/CD pipeline for continuous validation.
  4. Error Handling: Implement proper error handling to manage schema validation failures gracefully.
  5. Documentation: Maintain clear documentation for your schemas to facilitate easier updates and collaboration.

Conclusion

JSON schema validation is an essential practice in API testing, ensuring that your endpoints consistently return data in the expected format. Rest-Assured makes this process straightforward and efficient with its powerful features and easy-to-use syntax. By integrating JSON schema validation into your API tests, you can catch errors early, maintain high data quality, and ensure robust API performance.

In this article, we’ve covered the basics of setting up Rest-Assured, creating JSON schemas, and performing both simple and advanced schema validations. By following these guidelines and best practices, you can enhance the reliability and maintainability of your API tests, contributing to the overall success of your software projects.