一:json schema是做什么的?
1.用於描述現有的數據格式,定義JSON數據結構以及校驗JSON數據內容。
2.豐富的JSON校驗格式語法進行定制化開發,驗證JSON格式。
3.可以把JSON Schema理解為數據交換的一種虛擬”合同”,對數據進行一致性檢驗,保證數據正確的一種手段,所以一般在自動化測試過程中使用JSON Schema進行數據准確性校驗。
json生成schema工具 :https://tooltt.com/json2schema/
下邊來介紹一下各個關鍵字的含義:
1.$schema
用於指定JSON Schema的版本信息,draft-07 代表的就是版本,該關鍵字可以省略,當前最新版本是draft-07,可以在官網http://json-schema.org/中查看更多它的詳細說明。
2.title和description
用來描述JSON每個字段,title一般用來進行簡單的描述,而description一般是進行詳細的描述信息,這兩個關鍵字都可以省略。可以對最外層的信息進行描述,也可以對JSON中的列表層級、字段值等進行描述。
3.type
用於約束校驗的JSON元素的數據類型,比如最外層的type關鍵字值為object,校驗的JSON數據是一個JSON對象。而name下的type值為string,那么這個第一層級下的key(name)的數據類型為string。如果需要校驗的JSON數據中name的類型不為string就會校驗失敗。
Type其實就是JSON數據的基本數據類型,一般是有6種,加上null一共有7種:
Type取值 對應的Java數據類型
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結構的校驗可以理解為對每種不同數據類型的相應校驗。
1.對於object類型的關鍵字
properties、required、minProperties、maxProperties、propertyNames、dependencies、patternProperties、additionalProperties。
(1)properties
指定JSON對象中的各種不同key應該滿足的校驗邏輯,如果需要校驗的JSON對象中所有的值通過了定義的key對應的值,則通過校驗。
(2)required
這個關鍵字是數組,數組中的元素必須是字符串,必須是唯一的。這個關鍵字限制了JSON數據必須包含的key,需要注意的是required關鍵字指定的是這一級的key,所以如果有多級的話,那需要在多級里邊添加不同的required關鍵字來標識這個JSON對象必須要包含的key。
(3)minProperties、maxProperties
這兩個關鍵字的值都是非負整數。待校驗的JSON對象中一級key的個數限制,minProperties指定了待校驗的JSON對象可以接受的最少一級key的個數,maxProperties指定了待校驗JSON對象可以接受的最多一級key的個數。
(4)propertyNames
如果待校驗JSON對象中的每個一級key都能通過該關鍵字指定的JSON Schema的校驗,那么才認為待校驗的JSON對象通過校驗。注意,待校驗JSON對象的一級key都是string類型。
(5)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。
(6)additionnalProperties
如果待校驗JSON對象中存在,既沒有在properties中被定義,又沒有在patternProperties中被定義,那么這些一級key必須通過additionalProperties的校驗。
2.對於array類型的關鍵字
items、additionalItems、minItems、maxItems、uniqueItems、contains
(1)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]
(2)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"]
(4)minItems、maxItems
在校驗JSON數組中元素的個數限制,minItems指定了待校驗JSON數組可以接受的最少元素個數,而maxItems指定了待校驗JSON數組可以接受的最多元素個數。
(5)uniqueItems
這個關鍵字是一個boolean類型的值,關鍵字的值為true時,只有待校驗JSON數組中的所有元素都具有唯一性時,才能通過校驗。當該關鍵字的值為false時,任何待校驗JSON數組都能通過校驗。
(6)contains
在要校驗JSON數組中至少有一個元素能夠通過該關鍵字指定的JSON Schema的校驗,整個數組才算通過校驗。
3.對於integer或number類型的關鍵字
multipleOf、maximum、exclusiveMaximum、minimum、exclusiveMinimum
(1)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.0 }
那么,2、2.0、4、4.0都是可以通過校驗的,但是,3、3.0都是無法通過校驗的。
(2)maximum
該關鍵字的值是一個number,即可以是int,也可以是float。
該關鍵字規定了待校驗元素可以通過校驗的最大值。
(3)exclusiveMaximum
該關鍵字通常和maximum一起使用,當該關鍵字的值為true時,表示待校驗元素必須小於maximum指定的值;當該關鍵字的值為false時,表示待校驗元素可以小於或者等於maximum指定的值。
(4)minimum、exclusiveMinimum
minimum、exclusiveMinimum關鍵字的用法和含義與maximum、exclusiveMaximum相似。唯一的區別在於,一個約束了待校驗元素的最小值,一個約束了待校驗元素的最大值。
4.對於string類型的關鍵字
maxLength、minLength、pattern、format
(1)maxLength
該關鍵字規定了待校驗JSON元素可以通過校驗的最大長度,待校驗JSON元素的最大長度必須小於或者等於該關鍵字的值。
(2)minLength
該關鍵字規定了待校驗JSON元素可以通過校驗的最小長度,即待校驗JSON元素的最小長度必須大於或者等於該關鍵字的值。
(3)pattern
只有待校驗JSON元素符合該關鍵字指定的正則表達式,才算通過校驗。
(4)format
該關鍵字的值只能是以下取值:
date-time(時間格式)、email(郵件格式)、hostname(網站地址格式)、ipv4、ipv6、uri、uri-reference、uri-template、json-pointer。
如果待校驗的JSON元素正好是一個郵箱地址,那么,我們就可以使用format關鍵字進行校驗,而不必通過pattern關鍵字指定復雜的正則表達式進行校驗。例如:
{
"type": "string",
"format": "email"
}
5.所有類型都可用的關鍵字
enum、const、allOf、anyOf、oneOf、not、default
(1)enum
該關鍵字的值是一個數組,該數組至少要有一個元素,且數組內的每一個元素都是唯一的。
如果待校驗的JSON元素和數組中的某一個元素相同,則通過校驗。否則,無法通過校驗。
注意,該數組中的元素值可以是任何值,包括null。
(2)const
如果待校驗的JSON元素的值和該關鍵字指定的值相同,則通過校驗。否則,無法通過校驗。
(3)allOf
該關鍵字的值是一個非空數組,只有待校驗JSON元素通過數組中所有的JSON Schema校驗,才算真正通過校驗。
(4)anyOf
該關鍵字的值是一個非空數組,如果待校驗JSON元素能夠通過數組中的任何一個JSON Schema校驗,就算通過校驗。
(5)oneOf
該關鍵字的值是一個非空數組,如果待校驗JSON元素能且只能通過數組中的某一個JSON Schema校驗,才算真正通過校驗。不能通過任何一個校驗和能通過兩個及以上的校驗,都不算真正通過校驗。
(6)not
只有待校驗JSON元素不能通過該關鍵字指定的JSON Schema校驗的時候,待校驗元素才算通過校驗。
(7)default
該關鍵字常常用來指定待校驗JSON元素的默認值,當然,這個默認值最好是符合要求的,即能夠通過相應的JSON Schema的校驗。
實例1:對一個json數據中的某個字段參數,進行校驗。該字段會有多個類型(string、number、integer)如果滿足其中一個類型,我們就讓它通過校驗
{ "code": 200, "data": [{ "refId": 5000929, "type": 3 }, { "refId": "50080275008027", "type": 3 } ] }
可以看到data是一個數組(array),數組中有兩個json對象(object),兩個對象中的
"refId"字段,對應的值是不同類型的,第一個是number類型數據、第二個是string類型數據。所以表達
"refId"字段對應的值有多個,可以用
"anyOf"關鍵字,如下表示類型(type)
"refId": { "anyOf": [
{"type": "number"},
{"type": "string"}
] }
實例一:
返回字段json數據
{ "success": true, "data": { "bindMobile": true, "multiAuth": false, "mobileNumber": "19801150325", "notifyNumber": "19801150325", "secondaryType": null, "bindMobileUrl": null, "casLoginUrl": "https://don.com/cas/login?type=SSO_TICKET&ticket=c2b5tpe%3Ftype%3Dcas" }, "errorMsg": null, "message": null, "errorCode": 0 }
以下是對上面,返回的json數據進行的校驗格式約束
var schema = { "type": "object", "required": ["success","data"], "properties": { "success": { "type": "boolean" }, "data": { "type": "object", "required": ["bindMobile","multiAuth"], "properties": { "bindMobile": { "type": "boolean" }, "multiAuth": { "type": "boolean" }, "mobileNumber": { "type": "string" }, "notifyNumber": { "type": "string" }, "secondaryType": { "type": "null" }, "bindMobileUrl": { "type": "null" }, "casLoginUrl": { "type": "string" } } }, "errorMsg": { "type": "null" }, "message": { "type": "null" }, "errorCode": { "type": "number" } } } pm.test("Schema is valid", function () { pm.response.to.have.jsonSchema(schema) })
在Postman中的使用方法也很簡單,首先在Tests腳本中根據響應編寫JSON Schema結構模板,然后使用tv4.validate(jsonData, schema)進行驗證即可.
postman截圖:
校驗通過
總結:需要注意的是,返回中有null數據類型,所以類型寫成“null”