Advanced Validation
All Jikken tests include some form of response validation. At its simplest, this validation is just providing an expected status code or response body to be compared against the actual response. However, we may not always know the exact values that will be returned in our test.
This is where advanced validation comes in. This feature allows you to specify the expected response in a more flexible way, based on constraints instead of exact values. You may notice that the format is much the same as in data generation. We use the same principles of specifying a schema of data types and constraints here, but instead of generating a variable, we apply this structure to validating a response body.
Applying advanced validation
While we might normally define the response.body
field to validate that the response matches a literal JSON value, here we are validating the schema of the response, so we define our specification in the response.bodySchema
field instead.
In this example, we are specifying that the response should be an Object
, and it should have “field1” with a value of “value”, and “field2” with any 5-character string value.
This would correspond to the following JSON object:
As you can see, we can easily combine exact values with constraints to meet our own specific validation needs.
Let’s look at a few examples of validating data of different types. Though it is technically possible to validate any data type, since we are looking at response bodies here, we’ll focus on objects and lists as the base structures.
Validating objects
Object is naturally going to be the most common data type for a REST API response.
First, let’s expand on the previous example to show a more realistic case.
Here is something we might see if we were creating a new entity via an API.
We use type: Object
to specify that the response is an object.
Since the entity’s ID will be generated, we can’t know the exact value.
Instead, we can validate that the “id” field contains a positive integer.
We’re also checking that the “createdAt” field holds a timestamp which occurs after the time our test session was started.
NOW
is a built-in global variable that can be leveraged almost anywhere in your test file, as a replacement for the current timestamp at the time of session execution.
What if our ID is a UUID instead of an integer?
This version would match any 36-character string.
If you wanted to be more restrictive, type: String
also supports validating by pattern:
Using the pattern
constraint will validate that the field matches the specified regular expression.
In this case, a string in the form of a UUID, allowing only hexadecimal characters in the format {8}-{4}-{4}-{4}-{12}
.
Just like in data generation, schemas can also be nested inside one another, as in the case of a nested object structure.
Here, we have a field called “metrics” which contains a nested object.
It has its own schema
with its fields defined inside - in this case, a decimal “average” and an integer “median”.
This nesting can continue for as many levels as are needed, to support any data structure.
Validating lists
We can also validate lists in much the same way.
In this simple case, we’re specifying that the response body should be type: List
, and contain exactly 5 non-empty string values.
Realistically, our list would probably contain objects instead:
This is the same object schema as in our earlier example, but in this case, we are expecting a list of 5 objects in our response.
As with nested objects, we can also nest Object
and List
types together to create more complex structures.
Let’s say we have a set of IDs that we are expecting in the response:
This validates that each item’s “id” field is one of the values in the set specified by anyOf
.
Note that this will not validate that each ID is different, or that all three values are present. We have plans to expand list validation to be more flexible in the future.
Type reference
This section contains examples with all valid fields for each supported data type, for easy reference. Examples for simple types are shown as fields nested inside an object schema, but these could also be used with lists, or on their own.
For details and descriptions of each field, see the Full Format page.
Boolean
Validates a boolean value. The alias Bool
is also supported.
Integer
Validates an integer value. The alias Int
is also supported.
Float
Validates a float value.
String
Validates a string value.
Validates an email address.
In addition to the constraints specified, this type will also validate that the value is in a valid format for an email address.
Date
Validates a date value.
For details on format
syntax, see the Full Format page.
DateTime
Validates a date-time (or timestamp) value.
For details on format
syntax, see the Full Format page.
List
Validates a list. The type and constraints for items inside the list are specified in the schema
block.
Object
Validates an object. The fields inside the object and their types and constraints are specified in the schema
block.