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

实战:如何开始单元测试

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 等分支代码都执行了
    },
  },

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

相关推荐
Mintopia10 分钟前
计算机图形学学习指南
前端·javascript·计算机图形学
Mintopia10 分钟前
three.js 中的动画(animation)
前端·javascript·three.js
AI大模型顾潇12 分钟前
[特殊字符] Prompt如何驱动大模型对本地文件实现自主变更:Cline技术深度解析
前端·人工智能·llm·微调·prompt·编程·ai大模型
小小小小宇23 分钟前
React中 useEffect和useLayoutEffect源码原理
前端
AlexJee25 分钟前
在vue3中使用vue-cropper完成头像裁剪上传图片功能
前端
清晨細雨27 分钟前
uniapp微信小程序:WIFI设备配网之TCP/UDP开发AP配网
前端·物联网·小程序·uni-app
阿廖沙102428 分钟前
Rust核心概念
前端
阿廖沙102430 分钟前
🚀 从“值放哪了”聊起:Rust 内存管理通透讲解(适合前端工程师)
前端
打野赵怀真31 分钟前
如何提高前端应用的性能?
前端·javascript