前端单元测试那些事
很长一段时间以来,单元测试并不是前端工程师应具备的一项技能,但随着前端工程化的发展,项目日渐复杂化及代码追求高复用性等,促使单元测试愈发重要,决定整个项目质量的关键因素之一
1.单元测试的意义?
- 大规模代码重构时,能保证重构的正确性
- 保证代码的质量,验证功能完整性
2.主流的前端测试框架了解
2.1 框架对比(主流前三)
- Karma - 基于Node.js的JavaScript测试执行过程管理工具(Test Runner),让你的代码自动在多个浏览器(chrome,firefox,ie等)环境下运行
- Mocha - Mocha是一个测试框架,在vue-cli中配合chai断言库实现单元测试( Mocha+chai )
- jest -Jest 是 Facebook 开发的一款 JavaScript 测试框架。在 Facebook 内部广泛用来测试各种 JavaScript 代码
2.2 单元测试分类
- TDD - (测试驱动开发)侧重点偏向开发,通过测试用例来规范约束开发者编写出质量更高、bug更少的代码
- BDD - (行为驱动开发) 由外到内的开发方式,从外部定义业务成果,再深入到能实现这些成果,每个成果会转化成为相应的包含验收标准
简单来说就是TDD先写测试模块,再写主功能代码,然后能让测试模块通过测试,而BDD是先写主功能模块,再写测试模块
2.3 断言库
断言指的是一些布尔表达式,在程序中的某个特定点该表达式值为真,判断代码的实际执行结果与预期结果是否一致,而断言库则是讲常用的方法封装起来
主流的断言库有
- assert (TDD)
assert("mike" == user.name);
- expect.js(BDD) - expect() 风格的断言
expect(foo).to.be("aa");
- should.js - BDD(行为驱动开发)风格贯穿始终
foo.should.be("aa"); //should
- chai(BDD/TDD) - 集成了expect()、assert()和 should风格的断言
3.单元测试之 Jest 运用
Jest 是 Facebook 开源的一款 JS 单元测试框架,它也是 React 目前使用的单元测试框架,目前vue官方也把它当作为单元测试框架官方推荐 。 目前除了 Facebook 外,Twitter、Airbnb 也在使用 Jest。Jest 除了基本的断言和 Mock 功能外,还有快照测试、实时监控模式、覆盖度报告等实用功能。 同时 Jest 几乎不需要做任何配置便可使用。
我在项目开发使用jest作为单元测试框架,结合vue官方的测试工具vue-util-test
3.1 Jest 安装
npm install --save-dev jest
npm install -g jest
3.2 Jest的配置文件
(1)添加方式
- 自动生成 Jest.config.js
npx jest --init
然后会有一些选择,根据自己的实际情况选择
回车后会在项目目录下自动生成Jest.config.js配置文件,当然也可以选择第二种,手动创建
- 手动创建并配置 Jest.config.js
const path = require('path');
module.exports = {
verbose: true,
rootDir: path.resolve(__dirname, '../../../'),
moduleFileExtensions: [
'js',
'json',
'vue',
],
testMatch: [
'/src/test/unit/specs/*.spec.js',
],
transform: {
'^.+\.js$': 'babel-jest',
'.*\.(vue)$': 'vue-jest',
},
moduleNameMapper: {
'^@/(.*)$': '/src/$1',
},
transformIgnorePatterns: ['/node_modules/'],
collectCoverage: false,
coverageReporters: ['json', 'html'],
coverageDirectory: '/src/test/unit/coverage',
collectCoverageFrom: [
'src/components/**/*.(js|vue)',
'!src/main.js',
'!src/router/index.js',
'!**/node_modules/**',
],
};
配置解析:
- testMatch - 匹配测试用例的文件
- transform - 用
vue-jest
处理*.vue
文件,用babel-jest
处理*.js
文件 - moduleNameMapper - 支持源代码中相同的
@
->src
别名 - coverageDirectory - 覆盖率报告的目录,测试报告所存放的位置
- collectCoverageFrom - 测试报告想要覆盖那些文件,目录,前面加!是避开这些文件
(2)jest命令行工具
{
"name": "test",
"version": "1.0.0",
"scripts": {
"unit": "jest --config src/test/unit/jest.conf.js --coverage",
},
dependencies": {
"vue-jest": "^3.0.5",
},
"devDependencies":{
"@vue/test-utils": "^1.0.0-beta.13",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^21.2.0",
"jest": "^21.2.1",
}
}
- config - 配置jest配置文件路径
- coverage - 生成测试覆盖率报告 coverage是jest提供的生成测试覆盖率报告的命令,需要生成覆盖率报告的在package.json添加--coverage参数
(3) 单元测试文件命名
以spec.js结尾命名,spec是sepcification的缩写。就测试而言,Specification指的是给定特性或者必须满足的应用的技术细节
(4)单元测试报告覆盖率指标
执行: npm run unit
配置后执行该命令会直接生成coverage文件并在终端显示各个指标的覆盖率概览
在网页中打开coverage目录下的index.html就可以看到具体每个组件的测试报告
- 语句覆盖率(statement coverage)是否每个语句都执行了?
- 分支覆盖率(branch coverage)是否每个函数都调用了?
- 函数覆盖率(function coverage)是否每个if代码块都执行了?
- 行覆盖率(line coverage) 是否每一行都执行了?
当我们完成单元测试覆盖率达不到100%,不用慌,不用过度追求100%的覆盖率,把核心的功能模块测通即可,当然如果你要设置最低的覆盖率检测,可以在配置中加入如下,如果覆盖率低于你所设置的阈值(80%),则测试结果失败不通过
//jest.config.js
coverageThreshold: {
"global": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
}
},
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 8.深入k8s:资源控制Qos和eviction及其源码分析
- 1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知
- CNN不用乘法? AdderNet和DeepShift论文理解
- 动手构建地铁关系网,实现最短路径查询
- Java并发编程(08):Executor线程池框架
- 用Scipy求解单个正态总体的置信区间
- 架构设计 | 基于电商交易流程,图解TCC事务分段提交
- 用Gaussian做CASSCF计算
- 用Gaussian 16计算振动分辨的紫外-可见吸收光谱
- graylog日志分析系统上手教程
- 使用Seq搭建免费的日志服务
- 拜托!这才是分布式系统CAP的正确打开方式!
- 接口管理这下总会了吧?
- 交子杯 - 2020 - AI赛道 - TOP1
- Valine 一款快速、简洁且高效的无后端评论系统