接口响应断言神器 ---Json Schema

本贴最后更新于 1601 天前,其中的信息可能已经渤澥桑田

JSON Schema

1、介绍

JSON Schema是用来标记和校验JSON数据,类似于XMLSchema,可用在自动化测试验证JSON数据。

官网:http://json-schema.org/

最新版本:2019-09,最常用版本: draft 04。(目前各类编程语言对draft 04支持最广泛)

2、举个例子

假如你有一个接口响应数据,返回了用户信息注册相关的信息,内容如下:

{
    "code": 0,
    "msg": "OK",
    "data": {
        "id": 11712,
        "reg_name": "reg_name",
        "mobile_phone": "13212312395"
    },
    "copyright": "Copyright 柠檬班 © 2017-2019 湖南省零檬信息技术有限公司 All Rights Reserved"
}

在上面的例子中,注册接口要求提供code,msg,copyright,data4个成员,其中code是数值,msg、copyright是字符串,data是一个对象,data又包含了id、reg_name、mobile_phone3个成员。

如果想对code=0和msg=OK进行断言,可以使用JSON Schema来规范,对应的JSON Schema如下:

{
	"$schema": "http://json-schema.org/draft-04/schema#",
    "title": "register",
    "description": "register response",
    "type": "object",
    "properties": {
        "code": { 
        	"type": "integer", 
        	"minimum": 0,
            "maximum": 0
        },
        "msg": { "enum": ["OK"] }
    },
    "required": ["code", "msg"]
}

3、语法规则

既然JSON Schema是用来标记和校验JSON数据,那么咱们首先介绍下json中的数据类型,如下:

object:{"name": "zhangsan", "age": 13}
boolean:true,false
number:3.14,123
string:"lemonban"
array:["lemonban", "best", "test"]
null:null

通过上述6种类型自由组合可以构建更复杂的JSON结构,比如上面的用户注册响应结果。JSON Schema会针对这6种数据类型进行各种各样的约束。JSON Schema本身也是一种JSON数据,也要遵循JSON格式。

1、最外层字段
属性名称 描述
$schema 表示本次使用的版本
title 标题
description 描述
type 类型
properties 定义属性
required 必需属性
type可选值:
string :字符串
integer,number:integer整数,number数字
object:对象
array:数组
boolean:只能是true,false
null:null

例子:

{
	"type": "object",
	"properties": {
		"code": {"type": "integer"},
		"msg": {"type": "string"},
		"data": {
			"type": "array",
			"items": [
				{"type": "boolean"},
				{"type": "number"},
				{"type": "string"}
			]
		}
	}
}

符合要求的JSON:

{
    "code": 0,
    "msg": "OK",
    "data": [true,11.1,"hahaa"]
}
array常用属性:
items:array 每个元素的类型
minItems:数组最小的元素个数
maxItems:数组最大的元素个数
uniqueItems:每个元素都不相同,唯一

例子:

{
    "type": "array",
    "items": {
    	"type": "string"
    },
    "minItems": 1,
    "maxItems": 2,
    "uniqueItems": true
}

符合要求的JSON:

["a","b"] 
或者
["a"] 
number常用属性:
multipleOf: 10, 必须为10的倍数
maximum: 20, 必须小于等于20
exclusiveMaximum: true, 必须有maximum属性,效果是去掉maximum等于范围
minimum: 5, 必须大于等于5
exclusiveMinimum: true, 必须有minimum属性,效果是去掉minimum等于范围

例子:

{
	"type": "number",
	"multipleOf":5,
	"minimum": 5,
	"maximum": 20,
	"exclusiveMaximum": true
}

符合要求的JSON:

5,10,15任意一个数字都可以

在number中没有等于的约束,那怎么解决呢?答案:minimum和maximum同一个值就行了比如说5,因为minimum>=5加上maximum<=5的取值范围只有5。

string常用属性:
maxLength:最大长度
minLength:最小长度
pattern:支持正则表达式

例子:

{
    "type": "string",
    "minLength": 1,
    "maxLength": 5
}

符合要求的JSON:

1-5之内的字符串都可以例如:"A","12345"

在string中没有等于的约束,怎么解决呢?两种方式,第一种是用正则表达式,但是不在这里展开讲,有兴趣的小伙伴可以看我另一篇《正则表达式,看着一篇就够了》。第二种是用枚举enum。

枚举enum:
{
    "type": "string",
    "enum": ["a", "b", "c"]
}

符合要求的JSON:

"a"或者"b"或者"c"其中一个,如果想实现字符串等于某个值,写成这样:"enum": ["a"],目前枚举只支持string类型。
内部引用definitions和$ref :

definitions用来定义公共约束,注意definitions只是定义约束如果没有引用则约束不生效。$ref用来引用definitions中定义的约束。

例子:

{
	"definitions": {
		"mobilephone": {
			"type": "string",
			"pattern" : "^1[35678]\\d{9}$"
		}
	},
	"type": "object",
	"properties": {
		"mobilephone_1": {"$ref": "#/definitions/mobilephone"},
		"mobilephone_2": {"$ref": "#/definitions/mobilephone"}
	},
	"required":["mobilephone_1","mobilephone_2"]
}

上述jsonschema描述:必须是Object类型,并且有mobilephone_1和mobilephone_2属性,属性的约束来自definitions#mobilephone。

符合要求的JSON:

{
	"mobilephone_1" : "13212312312",
	"mobilephone_2" : "13212312312"
}
聚合关键字allOf、anyOf、oneOf、not
  1. allOf 必须满足所有的约束才算通过

例子:

{
	"definitions": {
		"mobilephone":  {
			"allOf": [ { "type": "string" }, { "maxLength": 5 } ] 
		}
	},
	"type": "object",
	"properties": {
		"mobilephone_1": {"$ref": "#/definitions/mobilephone"},
		"mobilephone_2": {"$ref": "#/definitions/mobilephone"}
	},
	"required":["mobilephone_1","mobilephone_2"]
}

符合要求的JSON:

{
	"mobilephone_1" : "1",
	"mobilephone_2" : "12345"
}
同时满足type=string,maxLength=5
  1. anyOf 必须满足任意一个或多个约束才算通过

例子:

{
	"definitions": {
		"mobilephone":  {
			"anyOf": [ { "type": "string" }, { "maxLength": 5 } ] 
		}
	},
	"type": "object",
	"properties": {
		"mobilephone_1": {"$ref": "#/definitions/mobilephone"},
		"mobilephone_2": {"$ref": "#/definitions/mobilephone"}
	},
	"required":["mobilephone_1","mobilephone_2"]
}

符合要求的JSON:

{
	"mobilephone_1" : 12345,
	"mobilephone_2" : "12345"
}
满足type=string或者maxLength=5一个或多个即可
  1. oneOf 必须满足任意一个约束才算通过

例子:

{
	"definitions": {
		"mobilephone":  {
			"anyOf": [ { "type": "string" }, { "maxLength": 5 } ] 
		}
	},
	"type": "object",
	"properties": {
		"mobilephone_1": {"$ref": "#/definitions/mobilephone"},
		"mobilephone_2": {"$ref": "#/definitions/mobilephone"}
	},
	"required":["mobilephone_1","mobilephone_2"]
}

符合要求的JSON:

{
	"mobilephone_1" : 123,
	"mobilephone_2" : "123456"
}
满足type=string或者maxLength=5中的一个,所以mobilephone_2:"12345"同时满足了2个反而不能通过。
  1. not 不是给出的约束即可

例子:

{
	"definitions": {
		"mobilephone":  {
			"not": { "type": "string" }
		}
	},
	"type": "object",
	"properties": {
		"mobilephone_1": {"$ref": "#/definitions/mobilephone"},
		"mobilephone_2": {"$ref": "#/definitions/mobilephone"}
	},
	"required":["mobilephone_1","mobilephone_2"]
}

符合要求的JSON:

{
	"mobilephone_1" : 123,
	"mobilephone_2" : false
}
不是string类型即可。
1 操作
luojie 在 2020-08-06 17:21:00 更新了该帖
回帖
请输入回帖内容 ...