JSON Schema Validation
Welcome to the JSON Schema Validation documentation!
While [assert.json] is great for checking specific fields, sometimes you need to validate the entire structure of a response—ensuring all required fields are present, types are correct, and no unauthorized fields exist. Rumour natively supports full JSON Schema (Draft 7) validation for this purpose.
The Test Payload
To make the following examples easy to understand, let's establish the exact response payload our mock server returns when making a GET request to /users/1.
All subsequent schema examples are validated against this specific JSON body:
{
"id": 1,
"email": "user@test.com",
"password": "pass123",
"name": "Test User",
"role": "user"
}
The schema Assertion
To validate a response against a JSON Schema, use the schema key inside your [assert] block. You can provide the schema as either a file path or an inline string.
Method 1: Using a Schema File (Recommended)
Using an external file is the recommended approach as it keeps your .toml files clean and allows you to share the same schema across multiple requests.
user_schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": { "type": "integer" },
"email": { "type": "string" },
"password": { "type": "string" },
"name": { "type": "string" },
"role": { "type": "string" }
},
"required": ["id", "email", "name", "role", "password"]
}
schema_demo.toml
name = "schema_demo"
[request]
method = "GET"
url = "{{base_url}}/users/1"
[assert]
status = 200
schema = "./user_schema.json"
Output (Success):
rumour run ./schema_demo.toml -v
GET http://localhost:4000/api/v2/users/1
URL: http://localhost:4000/api/v2/users/1
✓ SUCCESS: /home/bugsfounder/workspace/testing/assertion_examples/schema_demo.toml (2ms)
✓ ./schema_demo.toml → PASS (1 Pass, 0 Fail, 0 Skip)
╭──────────────────────────────────────────────────────────────────────────╮
│ RUMOUR EXECUTION REPORT │
├──────────────────────────────────────────────────────────────────────────┤
│ Total Requests: 1 │
│ Successful: 1 │
│ Failed: 0 │
│ Skipped: 0 │
│ Success Rate: 100.0% │
│ Total Time: 8ms │
╰──────────────────────────────────────────────────────────────────────────╯
✓ Successful Requests:
- /home/bugsfounder/workspace/testing/assertion_examples/schema_demo.toml [200] [8ms]
Rumour downloads your external user_schema.json file and checks every field against the response body, resulting in a successful run.
Method 2: Inline Schema
For simple or one-off validations, you can define the schema directly in the .toml file using a multi-line string (''').
schema_demo_inline.toml
name = "schema_demo_inline"
[request]
method = "GET"
url = "{{base_url}}/users/1"
[assert]
status = 200
schema = '''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": { "type": "integer" },
"email": { "type": "string" },
"name": { "type": "string" }
},
"required": ["id", "email", "name"]
}
'''
If the response violates the inline schema (e.g., if you changed id to require a string instead of an integer), Rumour halts execution and provides a comprehensive breakdown of all validation errors simultaneously:
Output (Failure Example):
Failure Intelligence:
! Node: /home/bugsfounder/workspace/testing/assertion_examples/schema_demo_fail.toml
Reason: JSON Schema: Schema validation failed: 1 is not of type "string"; "extra_missing_field" is a required property
Understanding JSON Schema (Draft-07)
When defining a schema, you will often notice the inclusion of the $schema keyword at the very top of the JSON payload. For Rumour, this should be set to Draft 7:
"$schema": "http://json-schema.org/draft-07/schema#"
What is it?
JSON Schema is a declarative vocabulary that allows you to define the expected structure, types, and constraints of your JSON data. Draft 7 is a widely adopted, mature, and highly stable version of this specification. It provides a standardized language to describe exactly what an API response should look like.
Why is it required?
The $schema keyword serves as a meta-schema declaration. It explicitly tells the validation engine exactly which "rulebook" or dialect to use when interpreting the document.
- Predictability: It ensures the engine doesn't guess the version, guaranteeing that advanced features (like conditional
if/then/elseconstraints) are processed accurately. - Tooling Support: Modern IDEs use this declaration to provide robust auto-completion, linting, and syntax highlighting while you author your schema.
How does it work?
JSON Schema operates on an additive constraint system. It systematically evaluates the response payload against the rules you define:
- Types (
type): Defines the expected data type for a given property (e.g.,string,integer,object,array). - Structure (
properties): Maps out the expected keys within an object and applies nested schema validations to their values. - Mandatory Fields (
required): A strict list of keys that must be present in the response object. If a key is missing, validation instantly fails.
Advanced Capabilities
JSON Schema Draft-07 provides incredibly robust logic for strict type enforcement and dynamic validation.
Validating Arrays
If your endpoint returns a list of items (e.g., GET /api/v2/users), you can use "type": "array" combined with the "items" keyword to validate the structure of every object within that list.
user_schema_array_pass.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"username": { "type": "string" },
"role": { "type": "string" },
"team": { "type": "string" }
},
"required": ["id", "username", "role", "team"]
}
}
schema_array_pass.toml
name = "schema_array_pass"
[request]
method = "GET"
url = "{{base_url}}/users"
[assert]
status = 200
schema = "./user_schema_array_pass.json"
Formats, Patterns & Enums
You can go beyond basic types (string, integer) and enforce strict string formatting.
format: Validates against built-in JSON Schema formats likeemail,date-time, oruuid.pattern: Validates the string against a Regular Expression.enum: Ensures the value matches one of a strictly predefined set of strings.
user_schema_advanced_types_pass.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email"
},
"role": {
"type": "string",
"enum": ["user", "admin"]
},
"password": {
"type": "string",
"pattern": "^pass\\d{3}$"
}
},
"required": ["email", "role", "password"]
}
schema_advanced_types_pass.toml
name = "schema_advanced_types_pass"
[request]
method = "GET"
url = "{{base_url}}/users/1"
[assert]
status = 200
schema = "./user_schema_advanced_types_pass.json"
Schema Strictness
By default, JSON Schemas are permissive—they allow extra fields not explicitly defined in your properties block. If you wish to fail validation when unauthorized or unexpected fields are returned, you must explicitly enforce strictness by defining "additionalProperties": false within your object schema.
The strictness engine evaluates identically regardless of whether the schema is inline or loaded from an external file. Below are three advanced examples demonstrating how strictness handles unauthorized properties, missing required properties, and typed additional properties.
Scenario 1: Rejecting Unauthorized Properties
If you enforce "additionalProperties": false and the server returns extra fields that aren't mapped in your schema, validation instantly fails.
user_schema_strict_fail.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": { "type": "integer" },
"email": { "type": "string" }
},
"required": ["id", "email"],
"additionalProperties": false
}
Output (Failure):
Failure Intelligence:
! Node: /home/bugsfounder/workspace/testing/assertion_examples/schema_external_strict_fail.toml
Reason: JSON Schema: Schema validation failed: Additional properties are not allowed ('name', 'password', 'role' were unexpected)
Scenario 2: Extra Required Properties Not Found in Response
If your schema demands properties that the API response completely omits, validation fails due to missing required fields (even if additionalProperties is set to false).
user_schema_extra_prop_fail.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": { "type": "integer" },
"email": { "type": "string" },
"password": { "type": "string" },
"name": { "type": "string" },
"role": { "type": "string" },
"age": { "type": "integer" },
"nickname": { "type": "string" }
},
"required": ["id", "email", "name", "role", "password", "age", "nickname"],
"additionalProperties": false
}
Output (Failure):
Failure Intelligence:
! Node: /home/bugsfounder/workspace/testing/assertion_examples/schema_external_extra_fail.toml
Reason: JSON Schema: Schema validation failed: "age" is a required property; "nickname" is a required property
Scenario 3: Typed Additional Properties
Instead of setting "additionalProperties": false, you can enforce that any unexpected fields map to a specific type constraint (like boolean). If the server returns extra fields that violate this constraint, it fails.
user_schema_additional_props_fail.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": { "type": "integer" },
"email": { "type": "string" }
},
"required": ["id", "email"],
"additionalProperties": {
"type": "boolean"
}
}
Output (Failure):
Failure Intelligence:
! Node: /home/bugsfounder/workspace/testing/assertion_examples/schema_external_add_props_fail.toml
Reason: JSON Schema: Schema validation failed: "Test User" is not of type "boolean"; "pass123" is not of type "boolean"; "user" is not of type "boolean"
Conditional Logic (if / then / else)
Because Rumour natively uses JSON Schema Draft-07, you can leverage advanced conditional logic directly within your assertions. This is incredibly powerful when an endpoint returns different payloads depending on the data state (e.g., a user's role).
In this example, we assert that if the returned role is "user", then the response must contain an age field. Since our mock server returns a "user" role but does not provide an age, this test will accurately fail the conditional block.
user_schema_conditional_fail.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"role": { "type": "string" }
},
"if": {
"properties": {
"role": { "const": "user" }
}
},
"then": {
"required": ["age"]
},
"else": {
"required": ["adminLevel"]
}
}
Output (Failure):
Failure Intelligence:
! Node: /home/bugsfounder/workspace/testing/assertion_examples/schema_conditional_fail.toml
Reason: JSON Schema: Schema validation failed: "age" is a required property
Output (Success):
If we change the schema to require a field that the response does contain (like email) when role is "user", the conditional logic will pass flawlessly.
user_schema_conditional_pass.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"role": { "type": "string" }
},
"if": {
"properties": {
"role": { "const": "user" }
}
},
"then": {
"required": ["email"]
},
"else": {
"required": ["adminLevel"]
}
}
✓ Successful Requests:
- /home/bugsfounder/workspace/testing/assertion_examples/schema_conditional_pass.toml [200] [3ms]
Caching & Performance
Rumour is highly optimized for performance. When running large suites, if multiple requests point to the same external schema file, Rumour compiles the schema only once and caches the validator in memory. This ensures that even with hundreds of schema validations, the overhead is near zero.