JSON Schema 的接口测试实战

2,749 阅读3分钟
原文链接: github.com

“接口返回的数据不对啊!”
我想这句话是前端工程师经常挂在嘴边的
作为前端工程师,与后端工程师对接口是日常工作,每次遇到接口问题,我们都无比头疼。既然这样,那我们能不能通过一种手段来处理这种问题呢?下面的 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 ,这种情况通过验证就是不通过。

这里贴一个 JSON Schema 官方的简单例子:

我们来简单分析下这个 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();

运行node index.js,返回
image

最后

这个例子很简单,但是到具体的业务中,对于所有(重要)接口的校验,还是需要不少的其他工作。比如

  • 分环境测试
  • 自动生成可配置的 JSON Schema
  • 定时/手动触发校验
  • 校验的上报与统计

其实我觉得这块也应该属于自动化测试的一个环节,目前还在探索和完善中。

JSON Schema 接口测试源码

最后,共勉! 💪

👆返回主页查看更多文章 👆