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

本贴最后更新于 743 天前,其中的信息可能已经时过境迁

什么是JSON Schema

JSON Schema,也称为JSON模式,下面一段话来自百度百科的介绍:
JSON Schema是描述你的JSON数据格式;JSON模式(应用程序/模式+ JSON)有多种用途,其中之一就是实例验证。验证过程可以是交互式或非交互式的。例如,应用程序可以使用JSON模式来构建用户界面使互动的内容生成除了用户输入检查或验证各种来源获取的数据。
一般使用JSON Schema来进行JSON数据格式验证,在数据提交到业务层次之前进行JSON格式的验证。
jsonschema百度百科

JSON Schema官网的描述摘要:http://json-schema.org/

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

下面是一段JSON示例:
文档中包含如下信息:

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

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

如果在自动化测试中需要来验证上述问题,方法一可以通过提取数据的方式完成,参考之前我写过的文章:
使用 JsonPath 完成接口自动化测试中参数关联和数据验证
使用JsonPath更适合关键信息的提取和验证,JSON Schema更适合回答上面的这些问题。

开始写JSON Schema

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

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

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/teacher.schema.json",
  "title": "老师信息",
  "description": "柠檬班的一个老师信息",
  "type": "object"
}

定义属性

teacherId 属性

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

最后的JSON Schema如下:

{
   "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/teacher.schema.json",
  "title": "老师信息",
  "description": "柠檬班的一个老师信息",
  "type": "object",
  "properties": {
    "teacherId": {
      "description": "老师信息的唯一标识符",
      "type": "integer"
    }
  },
  "required": [ "teacherId" ]
}

teacherName 属性

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

{
   "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/teacher.schema.json",
  "title": "老师信息",
  "description": "柠檬班的一个老师信息",
  "type": "object",
  "properties": {
    "teacherId": {
      "description": "老师信息的唯一标识符",
      "type": "integer"
    },
    "teacherName": {
      "description": "老师的名称",
      "type": "string"
    }
  },
  "required": [ "teacherId","teacherName" ]
}

age 属性

{
   "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/teacher.schema.json",
  "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属性要求如下:

JSON Schema需要做如下修改:

升级后JSON Schema如下

{
   "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/teacher.schema.json",
  "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 Schema
String jsonSchema = "{\r\n" + "   \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n"
		+ "  \"$id\": \"http://example.com/teacher.schema.json\",\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: 15
error: 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的知识可参考:

2 操作
happy 在 2020-09-14 17:37:54 更新了该帖
happy 在 2020-07-30 09:13:50 更新了该帖
3 回帖
请输入回帖内容 ...
  • briller

    Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.base.Platform.precomputeCharMatcher(Lcom/google/common/base/CharMatcher;)Lcom/google/common/base/CharMatcher;

    抛出这个错误,有遇到过么?一摸一样的代码

    image.png

  • happy

    添加如下依赖试试

    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>19.0</version>
    </dependency>
    
  • Lutra

    image.png
    image.png
    image.png
    您好,想问一下,json文件修改后,对于必须校验的字段,不进行校验了,是有什么地方错误吗