前言

Midwayjs框架已经内置了Jest测试工具,所以我们可以直接利用这个工具对我们写的代码编写测试代码,提升功能稳定性。

自己打算在公司内部先推行TDD(Test-Driven Development测试驱动开发),在写功能代码之前,先写测试代码。写测试代码的时候可以考虑一个功能可能会遇到什么问题,有哪些细节没有考虑到。

尽早发现问题,尽早解决,免得在开发完功能才发现问题,严重的时候甚至要推倒重来。

在观看该篇文章之前,建议先浏览一遍官方文档。此篇文章要讲的是在基于Midwayjs提供的测试Api基础上封装的测试脚本工具用法

使用范围

本封装工具只能用于提供Api测试,如果是要对某个模块甚至某段代码进行测试,请根据对应的测试需求自行开发代码。
Midwayjs官方测试文档中就举例了Service的测试案例,如果是要针对某段代码,可以import对应路径的代码文件后进行测试。

安装模块

  1. npm install -D @lzy-plugin/test-util

入门级使用

入门级使用只需要提供入参、期望结果即可,无需手写调用Jest API的代码

import {
  EXCEPT_RULE,
  executeTest,
  HTTP_METHOD,
  TestModel,
  TestModelItem,
} from '@@lzy-plugin/test-util';
import { createApp, close } from '@midwayjs/mock';
import { Framework } from '@midwayjs/web';

const array = new Array<TestModelItem>();
array.push({
  name: '测试用例1',
  path: '/admins/:admin_id', //admins/admin123?age=18&name=zhangsan
  method: HTTP_METHOD.PUT,
  param:{
      admin_id:'admin123'
  },
  query:{
    age:18,
    name:"zhangsan"
  },
  body: {
    username: '123456',
    password: '123456',
  },
  expectArray: [//期望结果数组
    {
      //工具提供的固定期望结果 用于入门级
      type: 'fixedExpect',//必须指定为fixedExpect
      key: 'result.status', //期望结果中要判断的key 格式为result.* 支持获取多层级的键值
      rule: EXCEPT_RULE.TO_BE,//判断规则 TO_BE 相等
      not:true, //对判断规则取反 判断规则变为不相等
      value: 200,//期待值 不等于200
    }
  ],
});

const testModel: TestModel = {
  name: '测试封装的测试工具',
  array: array,
};

executeTest(testModel,{
    async beforeAll(): Promise<IMidwayApplication> { //创建app实例
    let app = await createApp<Framework>();
    return app;
  },
  async afterAll(app: IMidwayApplication) { //关闭app实例
    await close(app);
  },
});//执行测试

运行结果示例:
image.png

常规使用

入门级毕竟是入门,存在一些问题,从上面的运行结果示例图片中的提示内容,基本上看不到执行语句前后的判断逻辑,更无法直接跳转定义的位置查看验证逻辑。
当你基本掌握Jest的Expect API文档,建议采用以下方式去定制期望结果的验证过程。

import {
  EXCEPT_RULE,
  executeTest,
  HTTP_METHOD,
  TestModel,
  TestModelItem,
} from '@lzy-plugin/test-util';
import { createApp, close } from '@midwayjs/mock';
import { Framework } from '@midwayjs/web';

const array = new Array<TestModelItem>();
array.push({
  name: '测试用例1',
  path: '/admins/:admin_id', //admins/admin123?age=18&name=zhangsan
  method: HTTP_METHOD.PUT,
  param:{
      admin_id:'admin123'
  },
  query:{
    age:18,
    name:"zhangsan"
  },
  body: {
    username: '123456',
    password: '123456',
  },
  expectArray: [//期望结果数组
    {
      label:'判断响应状态是否等于200',
      type: 'customExpect',//必须指定类型为customExpect
      callback: result => {//通过回调方法进行定制期望结果
        expect(result.status).toBe(200);
      },
    },
  ],
});

const testModel: TestModel = {
  name: '测试封装的测试工具',
  array: array,
};

executeTest(testModel,{
    async beforeAll(): Promise<IMidwayApplication> { //创建app实例
    let app = await createApp<Framework>();
    return app;
  },
  async afterAll(app: IMidwayApplication) { //关闭app实例
    await close(app);
  },
});//执行测试

运行结果示例:
image.png

分组使用

对期望结果设置groups进行分组,在执行时指定要执行的分组。

import {
  EXCEPT_RULE,
  executeTest,
  HTTP_METHOD,
  TestModel,
  TestModelItem,
} from '@lzy-plugin/test-util';
import { createApp, close } from '@midwayjs/mock';
import { Framework } from '@midwayjs/web';

const array = new Array<TestModelItem>();
array.push({
  name: '测试用例1',
  path: '/admins/:admin_id', //admins/admin123?age=18&name=zhangsan
  method: HTTP_METHOD.PUT,
  param:{
      admin_id:'admin123'
  },
  query:{
    age:18,
    name:"zhangsan"
  },
  body: {
    username: '123456',
    password: '123456',
  },
  expectArray: [//期望结果数组
    {
      label:'期待结果1',
      type: 'fixedExpect',//必须指定为fixedExpect
      key: 'result.status', //期望结果中要判断的key 格式为result.* 支持获取多层级的键值
      rule: EXCEPT_RULE.TO_BE,//判断规则 TO_BE 相等
      not:true, //对判断规则取反 判断规则变为不相等
      value: 200,//期待值 不等于200
      groups:['A']
    }
    {
      label:'期待结果2',
      type: 'customExpect',//必须指定类型为customExpect
      callback: result => {//通过回调方法进行定制期望结果
        expect(result.status).toBe(200);
      },
      groups:['B']  
    },
    {
      label:'期待结果3',
      type: 'customExpect',//必须指定类型为customExpect
      callback: result => {//通过回调方法进行定制期望结果
        expect(result.status).toBe(200);
      },
    },
  ],
});

const testModel: TestModel = {
  name: '测试封装的测试工具',
  array: array,
};

executeTest(testModel,{
    groups:['B'],
  async beforeAll(): Promise<IMidwayApplication> { //创建app实例
    let app = await createApp<Framework>();
    return app;
  },
  async afterAll(app: IMidwayApplication) { //关闭app实例
    await close(app);
  },
});//执行测试 将会执行期待结果2和期待结果3,期待结果1将被过滤,期待结果3没有指定任何分组,默认为通用的,所以会执行