前端单元测试实战:如何开始?

实战:如何开始单元测试

1.安装依赖

复制代码
npm install --save-dev jest

2.简单的例子

首先,创建一个 sum.js 文件

./sum.js

复制代码
function sum(a, b) {
  return a + b;
}

module.exports = sum;

创建一个名为 sum.test.js 的文件,这个文件包含了实际测试内容:

./test/sum.test.js

复制代码
const sum = require('../sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

将下面的配置部分添加到你的 package.json 里面

复制代码
{
  "scripts": {
    "test": "jest"
  },
}

运行 npm run test ,jest 将打印下面这个消息,如下图所示:

3.不支持部分 ES6 语法

nodejs 采用的是 CommonJS 的模块化规范,使用 require 引入模块;而 import 是 ES6 的模块化规范关键字。想要使用 import,必须引入 babel 转义支持,通过 babel 进行编译,使其变成 node 的模块化代码

如以下文件改写成 ES6 写法后,运行 npm run test将会报错

./sum.js

复制代码
export function sum(a, b) {
  return a + b;
}

./test/sum.test.js

复制代码
import { sum } from '../sum';

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

报错

为了能使用这些新特性,我们就需要使用 babel 把 ES6 转成 ES5 语法

解决办法

安装依赖

复制代码
npm install --save-dev @babel/core @babel/preset-env

根目录加入.babelrc

复制代码
{   "presets": ["@babel/preset-env"] }

再次运行 npm run test ,问题解决

原理

jest 运行时内部先执行( jest-babel ),检测是否安装 babel-core,然后取 .babelrc 中的配置运行测试之前结合 babel 先把测试用例代码转换一遍然后再进行测试

4.测试 ts 文件

jest 需要借助 .babelrc 去解析 TypeScript 文件再进行测试

安装依赖

复制代码
npm install --save-dev @babel/preset-typescript

**改写 **.babelrc

复制代码
{   "presets": ["@babel/preset-env", "@babel/preset-typescript"] }

为了解决编辑器对 jest 断言方法的类型报错,如 test、expect 的报错,你还需要安装

复制代码
npm install --save-dev @types/jest

./get.ts

复制代码
/**
 * 访问嵌套对象,避免代码中出现类似 user && user.personalInfo ? user.personalInfo.name : null 的代码
 */
export function get<T>(object: any, path: Array<number | string>, defaultValue?: T) : T {
  const result = path.reduce((obj, key) => obj !== undefined ? obj[key] : undefined, object);

  return result !== undefined ? result : defaultValue;
}

./test/get.test.ts

复制代码
import { get } from './get';

test('测试嵌套对象存在的可枚举属性 line1', () => {
  expect(get({
    id: 101,
    email: '[email protected]',
    personalInfo: {
      name: 'Jack',
      address: {
        line1: 'westwish st',
        line2: 'washmasher',
        city: 'wallas',
        state: 'WX'
      }
    }
  }, ['personalInfo', 'address', 'line1'])).toBe('westwish st');
});

运行 npm run test

5.持续监听

为了提高效率,可以通过加启动参数的方式让 jest 持续监听文件的修改,而不需要每次修改完再重新执行测试用例

改写 package.json

复制代码
"scripts": {     "test": "jest --watchAll"   },

效果

5.生成测试覆盖率报告

什么是单元测试覆盖率?

单元测试覆盖率是一种软件测试的度量指标,指在所有功能代码中,完成了单元测试的代码所占的比例。有很多自动化测试框架工具可以提供这一统计数据,其中最基础的计算方式为:

复制代码
单元测试覆盖率 = 被测代码行数 / 参测代码总行数 * 100%
如何生成?

加入 jest.config.js 文件

复制代码
module.exports = {
  // 是否显示覆盖率报告
  collectCoverage: true,
  // 告诉 jest 哪些文件需要经过单元测试测试
  collectCoverageFrom: ['get.ts', 'sum.ts', 'src/utils/**/*'],
}

再次运行效果

参数解读

参数名 含义 说明
% stmts 语句覆盖率 是不是每个语句都执行了?
% Branch 分支覆盖率 是不是每个 if 代码块都执行了?
% Funcs 函数覆盖率 是不是每个函数都调用了?
% Lines 行覆盖率 是不是每一行都执行了?

设置单元测试覆盖率阀值

个人认为既然在项目中集成了单元测试,那么非常有必要关注单元测试的质量,而覆盖率则一定程度上客观的反映了单测的质量,同时我们还可以通过设置单元测试阀值的方式提示用户是否达到了预期质量。

jest.config.js 文件

复制代码
module.exports = {
  collectCoverage: true, // 是否显示覆盖率报告
  collectCoverageFrom: ['get.ts', 'sum.ts', 'src/utils/**/*'], // 告诉 jest 哪些文件需要经过单元测试测试
  coverageThreshold: {
    global: {
      statements: 90, // 保证每个语句都执行了
      functions: 90, // 保证每个函数都调用了
      branches: 90, // 保证每个 if 等分支代码都执行了
    },
  },

上述阀值要求我们的测试用例足够充分,如果我们的用例没有足够充分,则下面的报错将会帮助你去完善

相关推荐
水银嘻嘻2 小时前
12 web 自动化之基于关键字+数据驱动-反射自动化框架搭建
运维·前端·自动化
小嘟嚷ovo3 小时前
h5,原生html,echarts关系网实现
前端·html·echarts
十一吖i3 小时前
Vue3项目使用ElDrawer后select方法不生效
前端
只可远观3 小时前
Flutter目录结构介绍、入口、Widget、Center组件、Text组件、MaterialApp组件、Scaffold组件
前端·flutter
周胡杰3 小时前
组件导航 (HMRouter)+flutter项目搭建-混合开发+分栏效果
前端·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
敲代码的小吉米3 小时前
前端上传el-upload、原生input本地文件pdf格式(纯前端预览本地文件不走后端接口)
前端·javascript·pdf·状态模式
是千千千熠啊3 小时前
vue使用Fabric和pdfjs完成合同签章及批注
前端·vue.js
九月TTS4 小时前
TTS-Web-Vue系列:组件逻辑分离与模块化重构
前端·vue.js·重构
我是大头鸟5 小时前
SpringMVC 内容协商处理
前端
Humbunklung5 小时前
Visual Studio 2022 中添加“高级保存选项”及解决编码问题
前端·c++·webview·visual studio