Testing
August 11, 2026 ยท View on GitHub
Warning
JSON Schema Draft 2 and older are not supported at this point in time.
jsonschema test [schemas-or-directories...]
[--http/-h] [--verbose/-v] [--debug/-g]
[--header/-H "<name>: <value>"]
[--resolve/-r <schemas-or-directories> ...]
[--extension/-e <extension>] [--ignore/-i <schemas-or-directories>]
[--default-dialect/-d <uri>] [--json/-j] [--format-assertion/-F]
[--jobs/-J <count>]
Schemas are code. As such, you should run an automated unit testing suite against them. Just like popular test frameworks like Jest, GoogleTest, and PyTest, the JSON Schema CLI provides a schema-oriented test runner inspired by the official JSON Schema test suite.
If you want to validate that a schema adheres to its metaschema, use the
metaschema command instead.
Pass --json to output results in CTRF (Common Test Report
Format), a standardized JSON format for test results that
integrates with CI/CD tools and test result dashboards.
Test suites run in parallel, defaulting to as many jobs as there are CPU
cores. Use --jobs/-J to control the level of parallelism. Note that when
running more than one job, suites report in completion order rather than in
input order, unless you pass --json, which always reports in input order.
Pass --jobs 1 to run suites serially in input order. Peak
memory usage grows with the number of jobs, as each job holds a compiled
schema in memory. Keep in mind that when combined with --verbose or
--debug, log lines from concurrent jobs may interleave on standard error.
Writing tests
To test a schema, you define one or more test suite (i.e. collections of tests) as JSON files that follow a specific format:
-
target: The URI of the schema you want to test, which must be imported into the resolution context using the--resolveor--httpoptions.If the
targetis relative, it will be interpreted as a file path relative to the test file location. A test document read from standard input has no location of its own, so its relative paths are interpreted against the current working directory instead.This property may also be set to a non-empty array of URIs, in which case every test case in
testswill be run against each of the listed schemas in turn. This is convenient for asserting that a single set of instances is accepted (or rejected) the same way by multiple related schemas. -
tests: An array of tests you want to run.
Tip
You can test different portions of a large schema by passing a schema URI
that contains a JSON Pointer in the target property. For example:
https://example.com/my-big-schema#/definitions/foo.
Every item in the tests array must be an object with the following
properties:
valid: A boolean that determines whether the given instance is expected to be valid or not against the target schema. In other words, if this property istrue, the test passes when the instance successfully validates against the schema. Conversely, if this property isfalse, the test passes when the instance does NOT validate against the schemadescription: An optional string property to make test output more readable
And either of the following properties, but not both:
data: The instance that you want to test against the target schema.dataPath: The instance that you want to test against the target schema, loaded from an external file instead
Additionally, if the schema under test is annotated with the x-jsonld-*
keywords of the rdf command, a test that sets valid to
true may declare either of the following properties, but not both, to also
assert on the promotion of the instance to JSON-LD:
rdf: The expected promotion of the instance to JSON-LD in expanded form, which is always an arrayrdfPath: The expected promotion of the instance to JSON-LD in expanded form, loaded from an external file instead
The comparison takes place against the canonical expanded form, so a
convenient way to author the expectation is to run the
rdf command and copy its output. Note that unlike that
command, the test runner does not reject schemas whose base dialect predates
JSON Schema 2019-09. The x-jsonld-* keywords of older schemas do not emit
annotations, so their instances always promote to the empty array [].
For example, here is a minimal test suite that expects an object with two
properties (foo and bar) to successfully validate against the target schema
https://example.com/my-schema-id:
{
"target": "https://example.com/my-schema-id",
"tests": [
{
"description": "I expect to pass",
"valid": true,
"data": {
"foo": 1,
"bar": 1
}
}
]
}
Examples
This is a test suite definition that runs a few test cases against the official
JSON Schema Draft 4 meta-schema. The first test asserts that the instance {}
is valid. The second test asserts that a schema where the type keyword is set
to an integer is invalid. The third test asserts that an instance loaded from a
relative path is valid against the schema:
{
"target": "http://json-schema.org/draft-04/schema#",
"$comment": "An arbitrary comment! Put whatever you want here",
"tests": [
{
"description": "The empty object is valid",
"valid": true,
"data": {}
},
{
"description": "The `type` keyword must be a string",
"valid": false,
"data": {
"type": 1
}
},
{
"description": "Load from an external file, relative to the test",
"valid": true,
"dataPath": "../my-data.json"
}
]
}
Assuming this file is saved as test/draft4.json, you can run it as follows:
jsonschema test test/draft4.json
Run a single test definition
jsonschema test path/to/test.json
Run every .json test definition in a given directory (recursively)
jsonschema test path/to/tests/
Run every .json test definition in the current directory (recursively)
jsonschema test
Run every .json test definition in the current directory while ignoring another
jsonschema test --ignore dist
Run every .test.json test definition in the current directory (recursively)
jsonschema test --extension .test.json
Run a single test definition enabling HTTP resolution
jsonschema test path/to/test.json --http
Run a single test definition with a custom HTTP header
jsonschema test path/to/test.json \
--http --header "Authorization: Bearer $REGISTRY_TOKEN"
Run a single test definition importing a single local schema
jsonschema test path/to/test.json --resolve path/to/external.json
Run a single test definition importing a directory of .schema.json schemas
jsonschema test path/to/test.json --resolve path/to/schemas --extension schema.json
Run a single test definition forcing every format to assert
The --format-assertion/-F option forces every format keyword in the
schema under test to behave as an assertion regardless of dialect or
vocabulary, which lets tests cover invalid-format cases without changing the
schema.
jsonschema test path/to/test.json --resolve path/to/schema.json --format-assertion