0%

Jest学习笔记

主流测试框架

  1. mocha
  2. jest

jest的优点

  1. 生态圈好
  2. 测试速度快
  3. API简单
  4. 隔离性好
  5. 可与各种IDE整合
  6. 多项目运行
  7. 展示测试覆盖率

环境搭建

  1. 随便创建一个文件夹,名称随意

  2. 通过 npm init -y 初始化

  3. 通过 cnpm i jest -Dyarn add jest --dev 安装 jest

  4. 新建 index.jsindex.test.js

  5. package.jsonscripts 里新增 "test": "jest"

  6. index.js 的内容如下

    function add(a, b) {
    return a > b ? 'a最大' : 'b最大'
    }


    module.exports = {
    add
    }
  7. index.test.js 的内容如下

    const { add } = require('./index')

    test('add方法 - 10, 20 ', () => {
    expect(add(10, 20)).toBe('b最大')
    })


    test('add方法 - 100, 20 ', () => {
    expect(add(100, 20)).toBe('a最大')
    })
  8. 执行 npm run testyarn test 查看测试结果

生成配置文件

在项目根目录下,执行以下命令

npx jest --init

image-20201218103007244

基本命令

开始测试

jest

生成测试覆盖率

npx jest --coverage

jest语法

toBe

代表严格相等,相当于 ===

test('测试toBe', () => {
expect('靓仔').toBe('靓仔'); // 左边 === 右边
})

toEqual

代表不严格相等,只要内容或结果,表面看上去相当就可以

test('测试toEqual', () => {
let obj = {name: '靓仔'};
expect(obj).toBe({name: '靓仔'}); // 左边 和 右边 看上去一样就行
})

toBeNull

只要匹配的值是 null 就匹配成功

test('测试toBeNull', () => {
let obj = null;
expect(obj).toBeNull(); // 只要obj是null,那么就通过测试
})

toBeUndefined

只要匹配的值是 undefined 就匹配成功

test('测试toBeUndefined', () => {
let obj = undefined;
expect(obj).toBeUndefined(); // 只要obj是undefined,那么就通过测试
})

toBeDefined

只要匹配的值不是 undefined 就匹配成功

test('测试toBeDefined', () => {
let obj = 1;
expect(obj).toBeDefined(); // 只要obj不是undefined,那么就通过测试
})

toBeTruthy

匹配 真值 ,只要匹配到的值属于 true 真值,就允许通过

test('测试toBeTruthy', () => {
let obj = 0;
expect(obj).toBeTruthy(); // obj是0,为假值,无法通过测试
})

toBeFalsy

匹配 假值 ,只要匹配到的值属于 false 假值,就允许通过

test('测试toBeFalsy', () => {
let obj = 0;
expect(obj).toBeFalsy(); // obj是0,为假值,通过测试
})

toBeGreaterThen

类似比较运算符 >

test('测试toBeGreaterThen', () => {
let num = 30;
expect(num).toBeGreaterThen(20); // 左边大于右边,则通过
})

toBeLessThen

类似比较运算符 <

test('测试toBeLessThen', () => {
let num = 0;
expect(num).toBeLessThen(20); // 左边小于右边,则通过
})

toBeGreaterThenOrEqual

类似比较运算符 >=

test('测试toBeGreaterThenOrEqual', () => {
let num = 30;
expect(num).toBeGreaterThenOrEqual(20); // 左边大于或等于右边,则通过
})

toBeLessThenOrEqual

类似比较运算符 <=

test('测试toBeLessThenOrEqual', () => {
let num = 20;
expect(num).toBeLessThenOrEqual(20); // 左边小于或等于右边,则通过
})

toBeCloseTo

解决浮点数运算可能会出现的错误行为,如 0.1 + 0.2 !== 0.3

test('测试toBeCloseTo', () => {
let a = 0.1;
let b = 0.2;
expect(a + b).toBeCloseTo(0.3);
})

toMatch

匹配字符串中是否存在某个字符

test('测试toMatch', () => {
let str = '黄某,黄某人,靓仔';
expect(str).toMatch('靓仔'); // str中存在 '靓仔' ,所以匹配通过
})

toContain

匹配数组、Set中是否存在某个值

test('测试toContain', () => {
let arr = ['黄某''黄某人''靓仔'];
expect(arr).toContain('靓仔'); // arr '靓仔' ,所以匹配通过
})

toThrow

匹配异常,只要测试的模块抛出异常,则通过,否则不通过

function throwErr() { throw Error('这是一个异常') };

test('测试toThrow', () => {
expect(throwErr).toThrow(); // 只要有异常抛出就通过

expect(throwErr).toThrow('这是一个异常'); // 只要抛出异常,且异常信息与右边一样,则通过

expect(throwErr).not.toThrow(); // 只要没有抛出 异常,则通过
})

采取ES6 Module

jest是不支持ES6方式进行模块导入的,只能采用 require 进行导入。

假如我们希望使用 ES6 模块方式进行导入,则需要使用 babel

  • 在项目根目录下安装2个包

    yarn add @babel/core@7.4.5 @babel/preset-env@7.4.5 --dev
  • 在项目的根目录下,新建 .babelrc ,内容如下

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

异步测试

假设我们要测试发送请求,而发送请求给服务器这个过程是 异步 的,那么我们可以这么来测试

  1. 回调函数的形式

    // index.js
    export const api = (fn) => {
    axios.get('xxx').then(res=>{
    fn(res.data);
    })
    }

    // index.test.js
    test('测试请求', (done) => {
    api(res => {
    expect(res).toEqual(xxx);
    done(); // 代表,执行到了这里,测试才算完成
    })
    })
  2. Promise形式

    // index.js
    export const api = () => {
    return axios.get('xxx');
    }

    // index.test.js
    test('测试请求', () => {
    // 一定要写return
    return api().then(res => {
    expect(res).toEqual(xxx);
    })
    })
  3. 捕获请求错误

    // index.test.js
    test('测试请求', () => {
    expect.assertions(1); // 断言,代表必须执行一次expect
    return api().catch(e => {
    expect(e.toString().indexOf('404') > -1).toBe(true);
    })
    })

    // 如果不写expect.assertions(1),那么不管是成功还是失败的请求都能通过测试
  4. async/await 形式

    // index.js
    export const api = () => {
    return axios.get('xxx');
    }

    // index.test.js
    test('测试请求', async () => {
    let res = await api();
    expect(res.data).toEqual(xxx);
    })

钩子函数

  1. beforeAll:在所有测试用例开始前,执行

    beforeAll(() => {
    console.log('这句话在所有测试用例全部执行之前,执行');
    })
  1. afterAll:在所有测试用例结束后,执行

    afterAll(() => {
    console.log('这句话在所有测试用例全部执行完后,执行');
    })
  1. beforeEach:在每一个测试用例开始执行前,执行

    before(() => {
    console.log('每一个测试用例开始执行前,都会执行一次');
    })
  1. afterEach:在每一个测试用例执行完成后,执行

    afterEach(() => {
    console.log('每一个测试用例执行完成后,都会执行一次');
    })

分组

如果我们把所有的测试用例都写在一个文件里,那么这个文件会变得很难看,如下:

// index.test.js
test('xxx1', () => {});
test('xxx2', () => {});
test('xxx3', () => {});
test('xxx4', () => {});
test('xxx5', () => {});
·······

解决这种问题,我们可以把不同模块的测试用例,分别拆分成几个文件,如 xx1.test.jsxx2.test.js

还可以借助 jest 给我们提供的describe 来给我们的测试用例进行分组:

describe('用户模块', () => {
test('用户登录', () => {});
test('用户注册', () => {});
test('修改密码', () => {});
})


describe('商品模块', () => {
test('商品预览', () => {});
test('商品购买', () => {});
test('商品收藏', () => {});
})

config

jest.config.js 配置

module.exports = { ... }

常用字段

  • moduleFileExtensions:解析的文件后缀

    类型:array

    默认:['js', 'jsx', 'ts', 'tsx', 'json', 'node']


  • automock: 测试的时候,自动mock数据

    类型:boolean

    默认:false


  • bail:经历多少次测试失败后,停止运行测试

    类型:boolean

    默认:0


  • clearMocks:在每个测试用例被调用前,自动清理mock的调用和实例,但不会删除已有的mock

    类型:boolean

    默认:false


  • collectCoverage:是否收集测试覆盖率的信息,可能会影响测试的执行速度

    类型:boolean

    默认:false


  • coverageDirectory:测试覆盖率信息保存的位置

    类型:string

    默认:undefined


  • coverageProvider:使用哪个 provider 来做代码覆盖测试

    类型:string

    默认:babel

    可选:v8


  • coverageReporters:用什么来生成测试报告

    类型:array

    默认:["json", "lcov", "text", "clover"]

    可选:['html-spa', 'html', 'json-summary', 'teamcity', 'cobertura', 'icovonly', 'text-lcov', 'text-summary'];


  • globals:创建一组全局变量,写在这里面的变量,在所有测试环境下都可以使用

    类型:object

    默认:{}


  • maxConcurrency:同时运行测试的数量

    类型:number

    默认:5


  • moduleNameMapper:路径别名

    类型:{}

    如可设置如下:

    module.exports = {
    moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1'
    },
    }
-------------本文结束    感谢阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!