JSON Schema的关键字详细介绍
参考文档:
https://json-schema.org/understanding-json-schema/reference/object.html
JSON Schema简介
JSON与XML相比有很多优势,JSON在各方面中的似有取代XML的趋势。JSON Schema是基于JSON格式的。
JSON Schema是
- 用于描述现有的数据格式,定义JSON数据结构以及校验JSON数据内容。
- 丰富的JSON校验格式语法进行定制化开发,验证JSON格式。
- 可以把JSON Schema理解为数据交换的一种虚拟”合同”,对数据进行一致性检验,保证数据正确的一种手段,所以一般在自动化测试过程中使用JSON Schema进行数据准确性校验。
json schema官网: http://json-schema.org/
json生成schema工具: https://jsonschema.net/#/
JSON Schema在接口自动化测试中发挥着结构和数据校验的角色。
Python中使用JSON Schema
- 使用
pip install jsonschema
。
Json Schema关键字
$schema、title、description、type、properties、required
Json Schema使用json格式来表示:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "这是title",
"description": "这是描述信息 ",
"type": "object",
"properties": {
"name": {
"description": "这是name的描述信息",
"type": "string"
}
},
"required": [
"name"
]
}
下边来介绍一下各个关键字的含义:
$schema
用于指定JSON Schema的版本信息,draft-07 代表的就是版本,该关键字可以省略,当前最新版本是draft-07,可以在官网http://json-schema.org/中查看更多它的详细说明。
title和description
用来描述JSON每个字段,title一般用来进行简单的描述,而description一般是进行详细的描述信息,这两个关键字都可以省略。可以对最外层的信息进行描述,也可以对JSON中的列表层级、字段值等进行描述。
type
用于约束校验的JSON元素的数据类型,比如最外层的type关键字值为object,校验的JSON数据是一个JSON对象。而name下的type值为string,那么这个第一层级下的key(name)的数据类型为string。如果需要校验的JSON数据中name的类型不为string就会校验失败。
Type其实就是JSON数据的基本数据类型,一般是有6种,加上null一共有7种:
Type取值 对应的Java数据类型:
json type | java type |
---|---|
object | Java.lang.Object |
array | Java.util.List |
integer | Int(java.lang.Integer) |
number | Float(java.lang.Float)或int |
boolean | Java.lang.Boolean |
string | Java.lang.String |
JSON Schema从Java的基本数据类型中对JSON结构进行校验,所以对JSON结构的校验可以理解为对每种不同数据类型的相应校验。
对于object类型的关键字
properties、required、minProperties、maxProperties、propertyNames、dependencies、patternProperties、additionalProperties。
properties
指定JSON对象中的各种不同key应该满足的校验逻辑,如果需要校验的JSON对象中所有的值通过了定义的key对应的值,则通过校验。
required
这个关键字是数组,数组中的元素必须是字符串,必须是唯一的。这个关键字限制了JSON数据必须包含的key,需要注意的是required关键字指定的是这一级的key,所以如果有多级的话,那需要在多级里边添加不同的required关键字来标识这个JSON对象必须要包含的key。
minProperties、maxProperties
这两个关键字的值都是非负整数。待校验的JSON对象中一级key的个数限制,minProperties指定了待校验的JSON对象可以接受的最少一级key的个数,maxProperties指定了待校验JSON对象可以接受的最多一级key的个数。
propertyNames
如果待校验JSON对象中的每个一级key都能通过该关键字指定的JSON Schema的校验,那么才认为待校验的JSON对象通过校验。注意,待校验JSON对象的一级key都是string类型。
patternProperties
正则表达式匹配json出现的属性,该JSON对象的每一个一级key都是一个正则表达式,用来匹配value值。
只有待校验JSON对象中的一级key,通过与之匹配的patternProperties中的一级正则表达式,对应的JSON Schema的校验,才算通过校验。例如,如果patternProperties对应的值如下:
{
"patternProperties": {
"^S_": {
"type": "number"
},
"^I": {
"type": "string"
}
}
}
在待校验JSON对象中,所有以S开头的key的value都必须是number,所有以I开头的一级key的value都必须是string。
additionnalProperties
如果待校验JSON对象中存在,既没有在properties中被定义,又没有在patternProperties中被定义,那么这些一级key必须通过additionalProperties的校验。
对于array类型的关键字
items、additionalItems、minItems、maxItems、uniqueItems、contains
items
当该关键字的值是一组有效的JSON Schema时,只有待校验JSON数组的所有元素通过items的值中对应位置上的JSON Schema的校验,那么,整个待校验JSON数组才算通过校验。
{
"type": "array",
"items": {
"type": "string",
"maxLength": 5
}
}
如果items定义的有效的JSON Schema的数量和待校验JSON数组中元素的数量不一致,那么就要采用“取小原则”。即,如果items定义了3个JSON Schema,但是待校验JSON数组只有2个元素,这时,只要待校验JSON数组的前两个元素能够分别通过items中的前两个JSON Schema的校验,那么,我们认为待校验JSON数组通过了校验。而,如果待校验JSON数组有4个元素,这时,只要待校验JSON数组的前三个元素能够通过items中对应的JSON Schema的校验,我们就认为待校验JSON数组通过了校验。
例如,如果items的值如下:
{
"type": "array",
"items": [
{
"type": "string",
"minLength": 5
},
{
"type": "number",
"minimum": 10
},
{
"type": "string"
}
]
}
上面的JSON Schema指出了待校验JSON数组应该满足的条件,数组的第一个元素是string类型,且最小可接受长度为5,数组的第二个元素是number类型,最小可接受的值为10,数组的第三个元素是string类型。那么下面这两个JSON数组明显是符合要求的,具体内容如下:
["green", 10, "good"]
["helloworld", 11]
additionalItems
需要注意的是,该关键字只有在items关键字的值为一组有效的JSON Schema的时候,才会进行校验,用于规定超出items中JSON Schema总数量之外的待校验JSON数组中的剩余的元素应该满足的校验逻辑。当然了,只有这些剩余的所有元素都满足additionalItems的要求时,待校验JSON数组才算通过校验。
其实,你可以这么理解,当items的值为一组有效的JOSN Schema的时候,一般可以和additionalItems关键字组合使用,items用于规定对应位置上应该满足的校验逻辑,而additionalItems用于规定超出items校验范围的所有剩余元素应该满足的条件。如果二者同时存在,那么只有待校验JSON数组同时通过二者的校验,才算真正地通过校验。
一般的JSON数据会出现某些场景下的字段个数并不是完全的匹配,所以这种场景也很常见。
如果一个additionalItems的值如下:
{
"type": "array",
"items": [
{
"type": "string",
"minLength": 5
},
{
"type": "number",
"minimum": 10
}
],
"additionalItems": {
"type": "string",
"minLength": 2
}
}
上面的JSON Schema的意思是,待校验JSON数组第一个元素是string类型,且可接受的最短长度为5个字符,第二个元素是number类型,且可接受的最小值为10,剩余的其他元素是string类型,且可接受的最短长度为2。那么,下面三个JSON数组是能够通过校验的,具体内容如下:
["green", 10, "good"]
minItems、maxItems
在校验JSON数组中元素的个数限制,minItems指定了待校验JSON数组可以接受的最少元素个数,而maxItems指定了待校验JSON数组可以接受的最多元素个数。
uniqueItems
这个关键字是一个boolean类型的值,关键字的值为true时,只有待校验JSON数组中的所有元素都具有唯一性时,才能通过校验。当该关键字的值为false时,任何待校验JSON数组都能通过校验。
contains
在要校验JSON数组中至少有一个元素能够通过该关键字指定的JSON Schema的校验,整个数组才算通过校验。
对于integer或number类型的关键字
multipleOf、maximum、exclusiveMaximum、minimum、exclusiveMinimum
multipleOf
该关键字的值是一个大于0的number,即可以是大于0的int,也可以是大于0的float。
只有待校验的值能够被该关键字的值整除,才算通过校验。
如果含有该关键字的JSON Schema如下:
{
"type": "integer",
"multipleOf": 2
}
那么,2、4、6都是可以通过校验的,但是,3、5、7都是无法通过校验的,当然了,2.0、4.0也是无法通过校验的。
如果含有multipleOf关键字的JSON Schema如下:
{
"type": "number",
"multipleOf": 2
}
那么,2、2.0、4、4.0都是可以通过校验的,但是,3、3.0都是无法通过校验的。
maximum
该关键字的值是一个number,即可以是int,也可以是float。
该关键字规定了待校验元素可以通过校验的最大值。
exclusiveMaximum
该关键字通常和maximum一起使用,当该关键字的值为true时,表示待校验元素必须小于maximum指定的值;当该关键字的值为false时,表示待校验元素可以小于或者等于maximum指定的值。
minimum、exclusiveMinimum
minimum、exclusiveMinimum关键字的用法和含义与maximum、exclusiveMaximum相似。唯一的区别在于,一个约束了待校验元素的最小值,一个约束了待校验元素的最大值。
对于string类型的关键字
maxLength、minLength、pattern、format
maxLength
该关键字规定了待校验JSON元素可以通过校验的最大长度,待校验JSON元素的最大长度必须小于或者等于该关键字的值。
minLength
该关键字规定了待校验JSON元素可以通过校验的最小长度,即待校验JSON元素的最小长度必须大于或者等于该关键字的值。
pattern
只有待校验JSON元素符合该关键字指定的正则表达式,才算通过校验。
format
该关键字的值只能是以下取值:
- date-time(时间格式)
- email(邮件格式)
- hostname(网站地址格式)
- ipv4
- ipv6
- uri
- uri-reference
- uri-template
- json-pointer。
如果待校验的JSON元素正好是一个邮箱地址,那么,我们就可以使用format关键字进行校验,而不必通过pattern关键字指定复杂的正则表达式进行校验。例如:
{
"type": "string",
"format": "email"
}
所有类型都可用的关键字
enum、const、allOf、anyOf、oneOf、not、default
enum
该关键字的值是一个数组,该数组至少要有一个元素,且数组内的每一个元素都是唯一的。
如果待校验的JSON元素和数组中的某一个元素相同,则通过校验。否则,无法通过校验。
注意,该数组中的元素值可以是任何值,包括null。
const
如果待校验的JSON元素的值和该关键字指定的值相同,则通过校验。否则,无法通过校验。
allOf
该关键字的值是一个非空数组,只有待校验JSON元素通过数组中所有的JSON Schema校验,才算真正通过校验。
anyOf
该关键字的值是一个非空数组,如果待校验JSON元素能够通过数组中的任何一个JSON Schema校验,就算通过校验。
oneOf
该关键字的值是一个非空数组,如果待校验JSON元素能且只能通过数组中的某一个JSON Schema校验,才算真正通过校验。不能通过任何一个校验和能通过两个及以上的校验,都不算真正通过校验。
not
只有待校验JSON元素不能通过该关键字指定的JSON Schema校验的时候,待校验元素才算通过校验。
default
该关键字常常用来指定待校验JSON元素的默认值,当然,这个默认值最好是符合要求的,即能够通过相应的JSON Schema的校验。