“接口返回的数据不对啊!”
我想这句话是前端工程师经常挂在嘴边的
作为前端工程师,与后端工程师对接口是日常工作,每次遇到接口问题,我们都无比头疼。既然这样,那我们能不能通过一种手段来处理这种问题呢?下面的 JSON Schema 就是我的一种尝试。
JSON Schema
JSON Schema is a vocabulary that allows you to annotate and validate JSON documents.
JSON Schema 是用以标注和验证JSON文档的元数据的文档。通俗的说,通过 JSON Schema 我们可以规范和验证 JSON 的格式,符不符合我们的预期。比如某个字段我们通过 JSON Schema 定义为 string
,但是返回的 JSON 中该字段是 number
,这种情况通过验证就是不通过。
我们来简单分析下这个 Schema 的含义:
- title 字段:用来描述这个 Schema 是用来做什么的,不具有约束性作用。
- properties 字段:用来描述这个 Schema 中包含的字段
- firstName,lastName,age 字段就是我们要描述的 JSON 中要包含的字段
- type 字段:用来描述字段的类型,这是必须的
- required 字段:用来描述哪些字段必须的
这时候,对于下面这个 JSON 就是不通过的,因为 Schema 中 age
定义的是 integer
。
{ "firstName": "z", "lastName": "q", "age": "61" }
check 接口
由于原来项目涉及公司信息,这里使用 demo 进行演示,但是思路是一样的。
jsonschema
其实 JSON Schema
本身描述起来是很复杂的。目前的版本是 draft-07。如果我们的接口是一些简单 JSON
还好,要是很复杂的话,想要写好那还是有些工作量的。所以这里我推荐大家使用 jsonschema,来帮助我们自动生成。然后,我们可以在这个基础上修改。
ajv
既然这里要检验我们的接口是否符合我们的预期,肯定是进行 校验
的。目前校验的库有不少,但是我使用的是 ajv 这个库。用它提供的功能,帮助我们校验,省去不少麻烦。
实战
这里校验 CNODE 的主题,请求接口是
https://cnodejs.org/api/v1/topics?page=1&limit=1
接口格式如下:
{
"success": true,
"data": [
{
"id": "5ae140407b0e8dc508cca7cc",
"author_id": "573ab7ba542374db1db0a436",
"tab": "share",
"content": "xxx",
"title": "【NODE PARTY】【上海】【6月9日 13:30】报名&答疑帖",
"last_reply_at": "2018-06-01T03:01:08.368Z",
"good": false,
"top": true,
"reply_count": 228,
"visit_count": 8080,
"create_at": "2018-04-26T02:58:08.067Z",
"author": {
"loginname": "aojiaotage",
"avatar_url": "https://avatars3.githubusercontent.com/u/8339316?v=4&s=120"
}
}
]
}
复制代码
通过 jsonschema 生成的 JSON Schema
如下:
{
"$id": "http://example.com/example.json",
"type": "object",
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"success": {
"$id": "/properties/success",
"type": "boolean",
"title": "The Success Schema ",
"default": false,
"examples": [
true
]
},
"data": {
"$id": "/properties/data",
"type": "array",
"items": {
"$id": "/properties/data/items",
"type": "object",
"properties": {
"id": {
"$id": "/properties/data/items/properties/id",
"type": "string",
"title": "The Id Schema ",
"default": "",
"examples": [
"5ae140407b0e8dc508cca7cc"
]
},
....
}
复制代码
可以看到生成的 JSON Schema
非常的规范,我们可以通过设置,将非必须的字段都去掉。
通过 axios 发送请求,获取返回的报文
const axios = require('axios'); const API = require('../api/index'); /** * 描述:获取cnode topic */ const getTopic = function () { return new Promise((resolve, reject) => { axios.get(API.topic) .then((response) => { resolve(response); }) .catch((error) => { reject(error); }); }) } module.exports = getTopic;
然后对数据进行 JSON Schema
校验
const Ajv = require('ajv'); const ajv = new Ajv(); // options can be passed, e.g. {allErrors: true} const chalk = require('chalk'); // schema const topicSchema = require('./schemas/cnode.topic.json'); // json const getTopic = require('./json/cnode.topic.js'); // check Topic function checkTopic () { getTopic() .then((resp) => { const validate = ajv.compile(topicSchema); const valid = validate(resp.data); console.log('---------------------------------------'); console.log(chalk.green(`请求url: ${resp.request.path}`)); if (valid) { console.log(chalk.green(`校验成功: ${valid}`)); } else { console.log(chalk.red(`校验失败: ${validate.errors}`)); } console.log('---------------------------------------'); }) .catch((err) => { console.log('---------------------------------------'); console.log(chalk.red(`请求失败: ${err}`)); console.log('---------------------------------------'); }) } checkTopic();
最后
这个例子很简单,但是到具体的业务中,对于所有(重要)接口的校验,还是需要不少的其他工作。比如
- 分环境测试
- 自动生成可配置的
JSON Schema
- 定时/手动触发校验
- 校验的上报与统计
其实我觉得这块也应该属于自动化测试的一个环节,目前还在探索和完善中。
最后,共勉! 💪
👆返回主页查看更多文章 👆