前端单元测试框架Jest初识

对于一个完整的前端工程,单元测试是不可缺少的一部分。但我们之所以很少使用单元测试,是对单元测试的认知不够,所以接下来,我们了解一下什么是单元测试。

前端单元测试是什么?

检测目标是否符合标准而用专业的工具和方法验证,最终得到特定结果。
对于前端开发来讲,特定目标是指代码,工具就是我们需要用到的测试框架(库)、测试用例等。

常用工具

Mocha 和 Jest,在开发中,我推荐使用Jest,从下载量和stats量来看,Jest也远高于Mocha。参见:jest vs mocha

原理以及如何使用

test

第一步:yarn add --dev jest
第二步:添加命令
{
  "scripts": {
    "test": "jest"
  }
}
第三步: 配置

jest.config.js

module.exports = {
  // 是否显示覆盖率报告
  collectCoverage: true,
};

配置jest.config.js也可以使用 npx jest --init 命令帮我们初始化配置


image.png

通过 ts-jest 使用 TypeScript

yarn add ts-jest -D

添加配置 preset: "ts-jest"

babel.config.js

module.exports = {
  presets: [
    ["@babel/preset-env", { targets: { node: "current" } }],
    "@babel/preset-typescript",
  ],
};
第四步:编写测试代码

创建ts文件
图片一

创建*.test.ts测试文件,注意命名时遵循xxx.test.ts的命名规则
图片二
第五步:运行

yarn test
image.png
  • %stmts是语句覆盖率:是不是每个语句都执行了
  • %Branch分支覆盖率:是不是每个if代码块都执行了
  • %Funcs函数覆盖率:是不是每个函数都调用了
  • %Lines行覆盖率:是不是每一行都执行了
  • Uncovered Line #s:没有执行的代码行
断言

“断言”通常用于判断在某些逻辑条件下会执行某种预期的结果,Jest框架内置了丰富的断言语句Expect。
测试值的时候我们通常会使用expect来断言值的内容,用下面代码段举例,有一个sumAdd函数会反回数字加一的值,我们测试的代码

describe("index.ts", () => {
  test("test index", () => {
    // toBe 匹配器有种类似于object.is或者===
    expect(sumAdd(1)).toBe(2);
  });

  test("test index NaN", () => {
    expect(sumAdd(NaN)).toBe(0);
  });
});

在以上情况toBe是匹配器功能,匹配我们函数返回值和预期的值是否相等。像这样的匹配器官方提供很多,值得一提的匹配器是.toMatchInlineSnapshot,用来确保值与最近的快照匹配,用法例如以下代码段

describe("index.ts", () => {
  test("test index", () => {
    // toBe 匹配器有种类似于object.is或者===
    expect(sumAdd(1)).toBe(2);
    expect(sumAdd(1)).toMatchSnapshot();
  });

  test("test index NaN", () => {
    expect(sumAdd(NaN)).toBe(0);
    expect(sumAdd(NaN)).toMatchSnapshot();
  });
});

在运行yarn test之后,会在同级目录产生一个份文件,保存快照,后面每次运行快照时都会对比,可以执行yarn test – -u或者手动删除快照文件,如果代码有更新,我们可以jest --updateSnapshot更新缓存的文件
image.png

index.test.ts.snap就是我们快照的内容
image.png

参考源码位置:
image.png

image.png
生命周期勾子

jest提供了一些测试的生命周期API,可以辅助我们在每个case的开始结束做一些处理。列举4个主要的生命周期勾子:

  • afterAll:当前文件中的所有测试执行完成后执行 fn,如果 fn 是promise,jest 会等待timeout 毫秒,默认 5000
  • afterEach:每个 test 执行完后执行 fn,timeout 含义同上
  • beforeAll:同 afterAll,不同之处在于在所有测试开始前执行
  • beforeEach:同 afterEach,不同之处在于在每个测试开始前执行
image.png

参考源码位置:
image.png
模拟函数

使用模拟函数通过jest.fn()创建,如果没有函数定义会返回undefined,通过日志打印返回值如下:


image.png

假设我们要测试某循环函数的内部实现,这个函数为传入的数组中的每个元素调用一次回调函数,我们可以使用jest.fn()模拟回调函数,来测试循环函数的内部实现

image.png

所有的 mock 函数都有这个特殊的 .mock属性,它保存了关于此函数如何被调用、调用时的返回值的信息。Mock 有返回值,并且在测试期间也可以将测试值注入代码。


image.png

总结:以上是全文内容,简述关于Jest使用流程和方法,相信阅读之后您也可以尝试一下编写测试代码的快乐。

参考文章:https://juejin.cn/post/7039108357554176037

你可能感兴趣的:(前端单元测试框架Jest初识)