Postman is an excellent tool for testing APIs. The response for an API call can be validated against a JSON schema to ensure that the values are valid in terms of type and format. In this article, we will explore how external JSON files can be loaded into Postman to avoid duplication of schema, in turn, making the tests more maintainable.
Postman does not (as of v7.3.4) support the ability to reference external libraries and files. Which means that we will have to get the schema loaded in the environment variable to parse and use it.
Primer on JSON schema & Tiny Validator library
Before we begin, it would be wise to have some understanding of JSON schema and Tiny validator library which is used for the schema validation. For the purpose of demonstration, we have four entities Campaign, Media, Sponsor, and MediaType. Campaign requires an object of Media and optionally a Sponsor. Sponsor requires an object of Media.
The following are the schemas for the above-listed entities.
common-schema.json— Contains the schema for common elements that are to be reused across the entire application
advertisemet-schema.json— Contains schema for all elements corresponding to a module called advertisement in the application.
Following methods from tiny Validator can be used to validate the results from an API response:
These methods accept four parameters:
The first two are mandatory without which the validation won’t work. Passing
checkRecursion will recursively validate the nested schema. Setting
true will result in a schema error if there are any additional properties apart from those which were defined in the schema. This is the bare minimum about this library that we must know for writing the tests.
Next, we need to have some idea about
$id keywords in JSON Schema.
$ref gets logically replaced with the thing that it points to. This referenced section can be within the same file or in an external file. The value of
$ref is a URI, and the part after
# sign (pound sign) is “the fragment” or “named anchor” and is in a format called JSON Pointer.
Next in line is the
$id property. The value of
$idis a URI that serves two purposes:
- It declares a unique identifier for the schema. (Figure-4)
- It declares a base URI against which
$refURIs are resolved. (Figure-5)
$id given to a subschema, in this case, the address provides a way to refer to subschema without using JSON Pointer. This means you can refer to them by a unique name as shown in the below example (Figure-4).
In the case where
$id is used to provide the base URI, a subschema present in the same file can be referenced as
"$ref" : "#/definitions/sponsor" which essentially means :
- Go to the root of this document
- Find value with the key definition
- Within that object find the value of the key sponsor
Going back to our example, Media property in Campaign object expects an array of objects of the type Media. The schema for the array item must be specified against the items property. The schema for media is present in a separate file named common-schema.json (Figure-1). Here we are using absolute URI along with JSON pointer. The intent of using an absolute URI will be clear once we start writing the tests. Note that Postman does not make any network calls to the given URI.
Even though the value of a
$refis a URI, it is not a network locator, only an identifier. This means that the schema doesn’t need to be accessible at that URI, but it may be. It is basically up to the validator implementation how external schema URIs will be handled, but one should not assume the validator will fetch network resources indicated in
Setup for validation
The schema needs to be loaded into Postman’s environment variable before running tests for the collection. Include all schemas in the solution and add a controller for reading the schema files.
Add a folder to the collection right before any other requests are made and add requests to GetSchema action method.
In test tab for each request in the TestSetup folder, save the response to a unique environment variable. Paste the following code in the tests tab:
This setup gives you full IDE support for editing the JSON files and saves the time you would have spent trying to edit the JSON string in the single-line text box every time there were changes are made to the schema.
Finally, in order to validate the schema, all the required schemas which are currently available in the environment variables (stored as a string) must be parsed to JSON and registered in the Tiny Validator. This can be done using
tv4.addSchema(). It accepts two parameters URI and schema object. An important point to note is that the URI used for registering the schema overrides the value specified for
$id key in the JSON file while registering the schema. This means that the URI you use to register the schema in
tv4.addSchema() function must be used while specifying the JSON pointer. When all the required schemas are registered using the
tv4.addSchema() function, any references in the schema will be automatically resolved.
A response body similar to the one listed below would successfully pass the test.
tv4.validate() will stop at first error and return a false value. It would be ideal to have a list of all errors for a request.
tv4.validateMultiple() returns an array of validation result which can be iterated over to find the error details for a property. Remember to keep the console (Ctrl + Alt + C) window open when you are running the test.
To verify if the schema validation really works as expected we can alter the response making it invalid. Value for alternateName in sponsor → media is changed to a number instead of a string and an unknown property called aBadField is added as well.
The validation fails and the postman console logs the exact path and the cause of the error.
Hope this post saves you some time while testing your APIs. I would appreciate your constructive feedback in improving this post. Got any handy tips on validating the APIs? Let's discuss :)