Jest自动化测试使用

176 阅读4分钟

Jest

安装和配置

npm i jest --save-dev

配置支持ES6

"presets": [["@babel/preset-env", { "targets": { "node": "current" } }]]

生成配置文件

npx jest init

运行

// package.json
  "scripts": {
    "test": "jest",
    "coverage": "jest --coverage" // 生成覆盖率分析文件
  },
  • 会自动找寻项目下.test.js文件运行测试用例

简单用法

  • describe 划定作用域
  • it or test 测试
  • expect 预期,逻辑书写地方
  • 断言 例如toBe,做一次判断
describe('test scope', () => {
  it('test two', () => {
    expect(1 + 6).toBe(7);
  });
});

钩子函数

  • beforeEach 每个测试用例调用前都调用

  • beforeAfter 每个测试测试用例调用后都调用

  • beforeAll 仅仅在运行测试用例前运行一次

  • afterAll 仅仅在运行测试用例后运行一次

  • only 在运行测试用例时仅仅只运行这一个

适配器分类(断言)

1,常见的有toBe,判断是否相等,还有toEqual,判断值是否相等,比如对象数组这种的.

2,判断是否为真实性的适配器toBeNull是否null,toBeUndefined是否为undefined,toBeDefined是否定义了,toBeTruthy是否为真,toBefalsy是否为假.

3,数字相关类型的,toBeGreaterthan大于,toBeGreaterthanOrEqual大于等于,toBeLessthan小于,toBeLessthanOrEqual小于等于,另外还有判断小数的,由于精确度问题,所以toBe,和toEqual不能来判断小数,需要使用toBeCloseTo

4,字符串类型的可以使用toMatch来判断是否包含或者使用正则也行

5,toContain可以用来判断是否包含在数组或者对象内

6,toThrow可以用来判断是否会抛出错误

常用的就是以上这些,还有很多其他的在www.jestjs.cn/docs/expect…

异步函数的测试

运行时,消耗时间短的可以用以下方式

export const testAsyncFun = () => {
  return new Promise((resolve, reject) => {
    resolve(1);
  });
};


describe('test', () => {
// 1,只有当传入参数done运行时,才会认为该测试用例运行完毕,所以,只需要将done运行于then中即可
  it('test testAsyncFun one', done => {
    testAsyncFun().then(result => {
      expect(result).toBe(1);
      done();
    });
  });
// 2,利用async与await将异步改为同步即可
  it('test testAsyncFun two', async() => {
    const result = await testAsyncFun();
    expect(result).toBe(1);
  })
});

如果,需要测试的地方运用了setTimeout,setInterval,那么就会有等待时间长的问题

// 使用假的时间
jest.useFakeTimers();

const testAsyncFun = callback => {
    setTimeout(() => {
    callback && callback();
  }, 2000);
};

describe('test', () => {
  test('test testAsyncFun', () => {
  // mock一个函数,这个函数可以给我们提供信息,例如参数,返回值,调用情况
    const callback = jest.fn();
    testAsyncFun(callback);
    // 让当前正在等待的定时器跑完
    jest.runOnlyPendingTimers();
    expect(callback).toHaveBeenCalledTimes(1);
  });
});

  • runOnlyPendingTimers,让当前正在等待的定时器跑完,没有开始的并不会跑完
  • runAllTimers, 让全部的定时器跑完,没有开始的也会被执行
  • advanceTimersByTime(msToRun), 让当前的时间快进,也就是设定后可以直接进行到某段时间

测试存在真实接口,可以用mock模拟替换接口

方法1:
import axios from 'axios';
import { getJsonPlaceholder } from './src/dependencies/api/ticket/create.js';

// create.js
// export const getJsonPlaceholder = () => axios.get('http://localhost:3000/user')

// mock axios
jest.mock('axios');

describe('test', () => {
  it('test testAsyncFun', (done) => {
  // 通过设定axios所有get返回值,既可以继续测试,不请求真实接口
    axios.get.mockResolvedValue({name: 'pjm'});
    getJsonPlaceholder().then(data => {
      expect(data).toEqual({name: 'pjm'})
      done();
    })
  });
});
方法2:
// 需要到模拟Mock的路径建立__mocks__文件夹,创建同名文件,之后才会在引用的时候直接引用同名方法
jest.mock('../src/dependencies/api/ticket/create');
// create mock
// export const getJsonPlaceholder = () => {
//  return Promise.resolve({ name: 'pjm' });
// };
import { getJsonPlaceholder } from '../src/dependencies/api/ticket/create.js';
// 如果mock完文件后,但是有一些不想被Mock,可以通过requireActual导出
const { getJsonPlaceholder } = jest.requireActual('../src/dependencies/api/ticket/create.js');


describe('test', () => {
  it('test testAsyncFun', (done) => {
    getJsonPlaceholder().then(data => {
      expect(data).toEqual({name: 'pjm'})
      done();
    })
  });
});

快照

  • 一般作用于配置文件,或者组件,或者成型变化少的项目
import { ticketType } from 'src/dependencies/fields/ticket/detail/detail'
// ticketType = {
//  prop: 'ticket_type',
//  label: '工单类型',
//  type: 'select',
//  enums: TicketTypeEnums,
//  required: true
//}

describe('test', () => {
  it('test snapshot', () => {
  	expect(ticketType).toMatchSnapshot();
  });
});
  • 通过toMatchSnapshot,第一次会生成__snapshots__文件夹,并且生成在里面添加快照文件,之后重新测试的话,会自动匹配快照文件,看是否和之前一样,不一样就报错,看是否需要更新
import { ticketType } from './config';

describe('test', () => {
  it('test snapshot', () => {
    expect(ticketType).toMatchInlineSnapshot(`
      Object {
        "enums": Array [
          Object {
            "id": 1,
            "name": "REWORK",
            "value": "返工工单",
          },
          Object {
            "id": 2,
            "name": "EXPENSE",
            "value": "消耗品工单",
          },
          Object {
            "id": 3,
            "name": "ASSEMBLY",
            "value": "装配件工单",
          },
        ],
        "label": "工单类型",
        "prop": "ticket_type",
        "required": true,
        "type": "select",
      }
    `);
  });
});

  • 通过toMatchInlineSnapshot生成的快照会自动添加到参数中,不会生成新的文件来存储,但是需要配合prettier使用,所以需要安装这个先

Vue Test Utils

待续