龙空技术网

通过 JSON Schema 完成接口自动化测试的数据验证

软件测试芒果 27

前言:

今天朋友们对“java调用json接口”大概比较关切,看官们都想要分析一些“java调用json接口”的相关资讯。那么小编同时在网络上网罗了一些关于“java调用json接口””的相关知识,希望小伙伴们能喜欢,看官们一起来了解一下吧!

什么是 JSON Schema

JSON Schema,也称为 JSON 模式,下面一段话来自百度百科的介绍:

JSON Schema 是描述你的 JSON 数据格式;JSON 模式(应用程序/模式 + JSON)有多种用途,其中之一就是实例验证。验证过程可以是交互式或非交互式的。例如,应用程序可以使用 JSON 模式来构建用户界面使互动的内容生成除了用户输入检查或验证各种来源获取的数据。

一般使用 JSON Schema 来进行 JSON 数据格式验证,在数据提交到业务层次之前进行 JSON 格式的验证。

jsonschema 百度百科

JSON Schema 官网的描述摘要:

JSON Schema 是基于 JSON 格式定义 JSON 数据结构的规范用于描述现有的数据格式(JSON 数据)清晰的人机可读文档:定义的 JSON Schema 具有人类和机器都可读的特性使用 JSON Schema 可完成完整的 JSON 结构和数据验证可用于自动化测试和确保客户提交的数据质量(如下我们只讨论在自动化测试中的应用)

下面是一段 JSON 示例:

文档中包含如下信息:

一个老师的唯一标识符:teacherId一个老师的名称:teacherName老师的年龄:age老师的标签:tags

  {  "teacherId": 1,  "teacherName": "Happy",  "age": 18,  "tags": [ "JAVA", "Python","Automation" ]}

例子很简单,但是中间有些问题有待解决,这也是我们在自动化测试中可能会关注的信息,比如以下这些:

teacherId 是啥?teacherName 是必需的吗?年龄字段 age 可以为 0 吗?所有的标签都是字符串类型的值吗?

如果在自动化测试中需要来验证上述问题,方法一可以通过提取数据的方式完成,参考之前我写过的文章:

使用 JsonPath 完成接口自动化测试中参数关联和数据验证

使用 JsonPath 更适合关键信息的提取和验证,JSON Schema 更适合回答上面的这些问题。

开始写 JSON Schema

首先我们从如下一些关键字开始:

$schema:该关键字声明该模式是根据标准的特定草案编写的,主要用于版本控制,可省略$id:该关键字定义模式的 URI,可省略title 和 description:该 JSON Schema 的注释和描述信息,不会向验证的数据调节约束type:该关键字会定义 JSON 数据的第一个约束,比如是 JSON 对象还是数组

针对上述 JSON 案例初步编写的 JSON Schema 如下

  {  "$schema": ";,  "$id": ";,  "title": "老师信息",  "description": "柠檬班的一个老师信息",  "type": "object"}
定义属性teacherId 属性teacherId 是老师的唯一标识符,是不可缺少的teacherId 类型是整型

根据约束我们在上面 JSON Schema 更新如下:

添加一个属性验证的关键字(key):properties添加一个 teacherId 的 key,描述和约束如下: description:描述这个属性 type:属性类型添加一个 required 关键字(key),在列表中加入 teacherId,表示 teacherId 是必需的

最后的 JSON Schema 如下:

  {   "$schema": ";,  "$id": ";,  "title": "老师信息",  "description": "柠檬班的一个老师信息",  "type": "object",  "properties": {    "teacherId": {      "description": "老师信息的唯一标识符",      "type": "integer"    }  },  "required": [ "teacherId" ]}
teacherName 属性teacherName 是老师的名称老师的名称也是一个老师必需的信息老师的名称是字符串类型

添加对 teacherName 属性的约束后,JSON Schema 如下,其中:

往 properties 中加入了 teacherName 的描述和约束信息往 required 列表中加入 teacherName 字段

  {   "$schema": ";,  "$id": ";,  "title": "老师信息",  "description": "柠檬班的一个老师信息",  "type": "object",  "properties": {    "teacherId": {      "description": "老师信息的唯一标识符",      "type": "integer"    },    "teacherName": {      "description": "老师的名称",      "type": "string"    }  },  "required": [ "teacherId","teacherName" ]}
age 属性age 字段是数值类型,使用 number 约束约定柠檬班老师的年龄不能不能小于 18 岁,否则就算雇佣童工了使用 exclusiveMinimum 关键字表示年龄必须大于 18(不包含 18),使用 minimum 关键字指定年龄最小为 18 岁(包含 18 岁)

升级后 JSON Schema 如下

  {   "$schema": ";,  "$id": ";,  "title": "老师信息",  "description": "柠檬班的一个老师信息",  "type": "object",  "properties": {    "teacherId": {      "description": "老师信息的唯一标识符",      "type": "integer"    },    "teacherName": {      "description": "老师的名称",      "type": "string"    },    "age": {      "description": "老师的年龄",      "type": "number",      "minimum": 18    }  },  "required": [ "teacherId","teacherName","age" ]}
tags 属性

tags 属性要求如下:

老师标签不是必需的如果有 tags,那么至少要有一个标签所有的标签必需要是唯一的,一个老师的标签不能重复所有的标签必须要是文本

JSON Schema 需要做如下修改:

在 properties 中添加一个 tags 属性tags 的类型设置为 array引入 items 的约束关键字定义数组中的元素,如下约束类型为 string引入 minItems 关键字用于约束数组中最少元素数量引入 uniqueItems 关键字用于约束数组所有元素值是唯一的因为 tags 可选的,所有在 required 中我们没有添加该属性

升级后 JSON Schema 如下

  {   "$schema": ";,  "$id": ";,  "title": "老师信息",  "description": "柠檬班的一个老师信息",  "type": "object",  "properties": {    "teacherId": {      "description": "老师信息的唯一标识符",      "type": "integer"    },    "teacherName": {      "description": "老师的名称",      "type": "string"    },    "age": {      "description": "老师的年龄",      "type": "number",      "minimum": 18    },    "tags": {      "description": "老师的标签",      "type": "array",      "items": {        "type": "string"      },      "minItems": 1,      "uniqueItems": true    }  },  "required": [ "teacherId","teacherName","age" ]}
Java 中的 JSON Schema 的校验通过 maven 引入相关的 jar 包
  <dependency>    <groupId>com.github.java-json-tools</groupId>    <artifactId>json-schema-validator</artifactId>    <version>2.2.10</version></dependency>
编写程序校验
  //要校验的json字符串(如来自自动化测试中的响应结果)String jsonStr = "{\r\n" + "  \"teacherId\": 1,\r\n" + "  \"teacherName\": \"Happy\",\r\n" + "  \"age\": 18,\r\n"		+ "  \"tags\": [ \"JAVA\", \"Python\",\"Automation\" ]\r\n" + "}";//根据响应结果需求,编写的JSON SchemaString jsonSchema = "{\r\n" + "   \"$schema\": \"\",\r\n"		+ "  \"$id\": \"\",\r\n" + "  \"title\": \"老师信息\",\r\n"		+ "  \"description\": \"柠檬班的一个老师信息\",\r\n" + "  \"type\": \"object\",\r\n" + "  \"properties\": {\r\n"		+ "    \"teacherId\": {\r\n" + "      \"description\": \"老师信息的唯一标识符\",\r\n"		+ "      \"type\": \"integer\"\r\n" + "    },\r\n" + "    \"teacherName\": {\r\n"		+ "      \"description\": \"老师的名称\",\r\n" + "      \"type\": \"string\"\r\n" + "    },\r\n"		+ "    \"age\": {\r\n" + "      \"description\": \"老师的年龄\",\r\n" + "      \"type\": \"number\",\r\n"		+ "      \"minimum\": 18\r\n" + "    },\r\n" + "    \"tags\": {\r\n"		+ "      \"description\": \"老师的标签\",\r\n" + "      \"type\": \"array\",\r\n" + "      \"items\": {\r\n"		+ "        \"type\": \"string\"\r\n" + "      },\r\n" + "      \"minItems\": 1,\r\n"		+ "      \"uniqueItems\": true\r\n" + "    }\r\n" + "  },\r\n"		+ "  \"required\": [ \"teacherId\",\"teacherName\",\"age\" ]\r\n" + "}";//创建JsonSchema工厂JsonSchemaFactory factory = JsonSchemaFactory.byDefault();//通过jsonSchema获得对应JsonNode对象JsonNode schemaNode = JsonLoader.fromString(jsonSchema);//通过jsonStr字符串获得对应JsonNode对象JsonNode dataNode = JsonLoader.fromString(jsonStr);//通过jsonSchema的JsonNode对象获得JsonSchema对象JsonSchema schema = factory.getJsonSchema(schemaNode);//使用json-schema-validator中JsonSchema对象的validate方法对数据进行校验//获得处理的报告信息ProcessingReport processingReport = schema.validate(dataNode);//获取完整报告信息System.out.println(processingReport);//判断校验是否成功,如果为true表示成功,否则失败System.out.println(processingReport.isSuccess());
输出结果如下
  com.github.fge.jsonschema.core.report.ListProcessingReport: success--- BEGIN MESSAGES ---warning: the following keywords are unknown and will be ignored: [$id]    level: "warning"    schema: {"loadingURI":"#","pointer":""}    domain: "syntax"    ignored: ["$id"]---  END MESSAGES  ---true

最后校验的结果为 true,表述校验通过,说明我们的 JSON 数据不管从结果还是数据上都是符合要求的,

如果我们把老师的信息调整如下:

  {  "teacherId": 1,  "teacherName": "Happy",  "age": 15,  "tags": [ "JAVA", "JAVA","Automation" ]}

校验结果为:

  com.github.fge.jsonschema.core.report.ListProcessingReport: failure--- BEGIN MESSAGES ---warning: the following keywords are unknown and will be ignored: [$id]    level: "warning"    schema: {"loadingURI":"#","pointer":""}    domain: "syntax"    ignored: ["$id"]error: numeric instance is lower than the required minimum (minimum: 18, found: 15)    level: "error"    schema: {"loadingURI":"#","pointer":"/properties/age"}    instance: {"pointer":"/age"}    domain: "validation"    keyword: "minimum"    minimum: 18    found: 15error: array must not contain duplicate elements    level: "error"    schema: {"loadingURI":"#","pointer":"/properties/tags"}    instance: {"pointer":"/tags"}    domain: "validation"    keyword: "uniqueItems"---  END MESSAGES  ---false

校验结果 false,表述失败,处理报告中对校验不通过的地方也有原因描述

至此,大家可以在自己的自动化测试框架应用上 JSON Schema,对响应结果为 JSON 格式的数据进行完整的结构和数据校验

更多关于 JSON Schema 的知识可参考:

:java-json-tools/json-schema-validator

标签: #java调用json接口