前端如何做好单元测试 前端开发自动化单元测试
zhezhongyun 2024-12-16 17:34 46 浏览
简介
日常我们都忙于写bug,有时候不妨停下脚步,找找bug。测试广义上分为黑盒测试和白盒测试。单元测试属于后者,是在知道程序运行逻辑的基础上,设计测试用例,确保程序模块行为与我们预期一致。
前端做单元测试的不多,但是并不代表不必要,对于一些复杂的数据处理、公共类库等,单元测试是非常有必要的,代码只要有修改,就是有风险的,检验代码正确与否,最安全的方法就是通过设计的所有测试用例。通过本文,你将会收获以下内容:
- Node.js中如何做单元测试,如何生成测试报告与测试覆盖率
- vue.js单文件组件如何从零开始搭建单元测试环境
Node.js单元测试
巧妇难为无米之炊,在做单元测试前,我们需要借助一款测试框架与一个断言库,测试框架是辅助我们编写测试用例,而断言主要是用来判断预期输出与实际输出是否一致。本文测试框架选用mocha,断言采用expect.js。
CommonJS与ES6模块化区别
现在前端开发环境几乎都运行在Node.js中,只是最后打包成静态资源文件。所以单纯只想针对单纯项目中JavaScript文件进行单元测试,会因为模块化的差异而执行失败,因为ES6中使用的是import/export,而CommonJS中使用的是require/module.exports,想了解Node.js 如何处理 ES6 模块,可以参考阮老师文章。本文推荐一个第三方类库esm,仅需两步就能实现Node.js加载ES6 module。使用流程如下:
- 安装
npm install esm -D
- 使用
const $require = require('esm')(module)
// 注意:如果是export default,导入的模块需要通过.default获取
const TestModule = $require('ES6Module.js')
测试代码
以下为测试代码,主要测试加法运算及函数柯里化处理过程是否正确。
class Calc {
constructor() {
this.add = this.addFun()
}
// 函数柯里化
addFun () {
let args = []
let calcFun = function (...params) {
args = args.concat(params)
return args.reduce((total, current) => {
return total + current
}, 0)
}
calcFun.clear = function () {
args = []
}
return calcFun
}
}
export default = Calc
编写测试用例
测试框架采用mocha,一般编写单元测试用例,离不开describe和it。describe类似于开发中的class,是一类测试用例的集合;it相当于普通function,是一个具体测试用例实现。如下为简单的测试用例,简单罗列了普通测试与异步测试的基本使用,更多使用方法可以参考mocha官网
const Calc = require('../class/calc.js')
const expect = require('expect.js')
const calcInstance = new Calc()
describe('Test calc add operation', function () {
it('should 1 + 2 === 3', function () {
expect(calcInstance.add(1, 2)).to.be(3)
});
it('should summary + 2 === 4', function () {
expect(calcInstance.add(2)).to.be(5)
});
it('should 1 + 2 === 3 after clear', function () {
// 指定当前测试用例超时时间
this.timeout(0)
calcInstance.add.clear()
// 异步测试
return new Promise(resolve => {
setTimeout(() => {
resolve()
}, 2000)
}).then(() => {
expect(calcInstance.add(1, 2)).to.be(3)
})
});
})
单元测试指标
覆盖率简述
覆盖率是单元测试核心指标,又细分为语句覆盖率(Statements)、分支覆盖率(Branches)、函数覆盖率(Functions)、行覆盖率(Lines)。一个比较好的单元测试用例,要保证被测试代码的关键逻辑都被测试用例覆盖到。如下为Calc类的单元测试覆盖率情况。
单元测试覆盖率统计
开源组件nyc可以帮助我们统计覆盖率情况。
- 安装
npm install nyc -D
- 配置文件
// nyc.config.js
module.exports = {
all: true,
include: [ // 包含测试文件
"web/src/lib/**.js",
".electron/class/**.js",
"web/src/**/*.js",
"web/src/**/*.vue"
],
exclude: [ // 排除测试文件
"web/test/*.spec.js",
".electron/test/*.spec.js"
],
checkCoverage: false, // 测试基准覆盖率
reporter: ['text', 'html'] // 测试报告格式
}
- 使用
// package.json
"test-add": "nyc mocha .electron/test/calc.spec.js"
可视化单元测试报告
mocha官方推荐使用mochawesome用于生成可视化测试报告,使用非常简单。
- 安装
npm install mochawesome -D
- 使用
// package.json
"test-add-reporter": "mocha .electron/test/calc.spec.js --reporter mochawesome --reporter-options reportDir=mochaReporter,reportFilename=addReporter"
注意事项
编写单元测试用例时,不仅要考虑测试覆盖率,还要考虑测试用例设计。合格的测试用例不仅要包含正常情况输入输出,也要包含异常情况输入输出的判断,不能以开发的思维去编写测试用例。
vue组件的单元测试
vue单文件组件测试官方脚手架也有集成,但是还是要抱着试一试的态度,去学习下如何从零开始搭建一个vue单文件组件测试环境。
.vue文件并不能直接执行,需要对其进行打包编译,转换成浏览器能识别的静态资源文件才行。目前有开源的工具mochapack可以提供这种能力。见名知意,普通mocha测试用例是可以直接执行的,但是遇到非javascript语法,就会执行报错。mochapack主要功能是在测试用例执行前利用webpack对测试用例进行编译转换,这样就不用担心执行出错。具体配置如下:
// 基础配置
{
"test-vue-sfc": "mochapack --webpack-config ./build/webpack.test.config.js --require ./web/test/setup.js web/test/demo.spec.js"
}
- --webpack-config 指定webpack配置文件
- --require 指定环境依赖状态,如nodejs中不存在dom,需要引入js-dom
- web/test/demo.spec.js 需要执行的测试用例
vue测试用例编写
测试用例是用nodejs执行,并没有浏览器环境,所以我们借助官方提供的测试工具@vue/test-utils对组件进行模拟挂载、点击等。使用方法也比较简单,以下为简单的测试用例。
import Vue from 'vue'
import ElementUI from 'element-ui'
import TestDemo from '../src/components/test-demo.vue'
import { shallowMount } from '@vue/test-utils'
Vue.use(ElementUI)
describe('Test test-demo.vue', function () {
this.timeout(0)
const wrapper = shallowMount(TestDemo)
wrapper.vm.count = 1
it('should summary === 1', function () {
expect(wrapper.vm.summary).to.be(1)
});
})
结语
对于通用性、处理逻辑复杂等模块单元,做单元测试收益会很大的,至少每次改动的对错,都能有一个较明显的反馈。单元测试不仅要注意一定程度的覆盖率,也要注意测试用例设计的合理性。完整代码可以参考electron-demo,这个项目是electron开发demo,里面是本人日常开发中常见的坑点,有兴趣的可以关注下。
相关推荐
- JavaScript做个贪吃蛇小游戏(过关-加速),无需网络直接玩。
-
JavaScript做个贪吃蛇小游戏(过关-则加速)在浏览器打开文件,无需网络直接玩。<!DOCTYPEhtml><htmllang="en"><...
- 大模型部署加速方法简单总结(大模型 ai)
-
以下对大模型部署、压缩、加速的方法做一个简单总结,为后续需要备查。llama.cppGithub:https://github.com/ggerganov/llama.cppLLaMA.cpp项...
- 安徽医大第一医院应用VitaFlow Liberty(R)Flex为患者焕然一“心”
-
近日,在安徽医科大学第一附属医院心血管内科负责人暨北京安贞医院安徽医院业务副院长喻荣辉教授的鼎力支持和卓越带领下,凭借着先进的VitaFlowLiberty(R)Flex经导管主动脉瓣可回收可...
- 300 多行代码搞定微信 8.0 的「炸」「裂」特效!
-
微信8.0更新的一大特色就是支持动画表情,如果发送的消息只有一个内置的表情图标,这个表情会有一段简单的动画,一些特殊的表情还有全屏特效,例如烟花表情有全屏放烟花的特效,炸弹表情有爆炸动画并且消息和...
- 让div填充屏幕剩余高度的方法(div填充20px)
-
技术背景在前端开发中,经常会遇到需要让某个div元素填充屏幕剩余高度的需求,比如创建具有固定头部和底部,中间内容区域自适应填充剩余空间的布局。随着CSS技术的发展,有多种方法可以实现这一需求。实现步骤...
- css之div内容居中(css中div怎么居中)
-
div中的内容居中显示,包括水平和垂直2个方向。<html><head><styletype="text/css">...
- 使用uniapp开发小程序遇到的一些问题及解决方法
-
1、swiper组件自定义知识点swiper组件的指示点默认是圆圈,想要自己设置指示点,需要获得当前索引,然后赋给当前索引不同的样式,然后在做个动画就可以了。*关键点用change方法,然后通过e.d...
- 微信小程序主页面排版(怎样设置小程序的排版)
-
开发小程序的话首先要了解里面的每个文件的作用小程序没有DOM对象,一切基于组件化小程序的四个重要的文件*.js*.wxml--->view结构---->html*.wxss--...
- Vue动态组件的实践与原理探究(vue动态组件component原理)
-
我司有一个工作台搭建产品,允许通过拖拽小部件的方式来搭建一个工作台页面,平台内置了一些常用小部件,另外也允许自行开发小部件上传使用,本文会从实践的角度来介绍其实现原理。ps.本文项目使用VueCLI...
- 【HarmonyOS Next之旅】兼容JS的类Web开发(四) -> tabs
-
目录1->创建Tabs2->设置Tabs方向3->设置样式4->显示页签索引5->场景示例编辑1->创建Tabs在pages/index目录...
- CSS:前端必会的flex布局,我把布局代码全部展示出来了
-
进入我的主页,查看更多CSS的分享!首先呢,先去看文档,了解flex是什么,这里不做赘述。当然,可以看下面的代码示例,辅助你理解。一、row将子元素在水平方向进行布局:1.垂直方向靠顶部,水平方向靠...
- 【HarmonyOS Next之旅】兼容JS的类Web开发(四) -> swiper
-
目录1->创建Swiper组件2->添加属性3->设置样式4->绑定事件5->场景示例编辑1->创建Swiper组件在pages/index...
- CSS:Flex布局,网页排版神器!(css3 flex布局)
-
还在为网页排版抓狂?别担心,CSS的flex布局来了,让你轻松玩转各种页面布局,实现网页设计自由!什么是Flex布局?Flex布局,也称为弹性布局,是CSS中的一种强大布局方式,它能够让你...
- 移动WEB开发之flex布局,附携程网首页案例制作
-
一、flex布局体验传统布局兼容性好布局繁琐局限性,不能再移动端很好的布局1.1flex弹性布局:操作方便,布局极为简单,移动端应用很广泛PC端浏览器支持情况较差IE11或更低版本,不支持或仅部...
- 2024最新升级–前端内功修炼 5大主流布局系统进阶(mk分享)
-
2024最新升级–前端内功修炼5大主流布局系统进阶(mk分享)获课》789it.top/14658/前端布局是网页设计中至关重要的一环,它决定了网页的结构和元素的排列方式。随着前端技术的不断发展,现...
- 一周热门
- 最近发表
-
- JavaScript做个贪吃蛇小游戏(过关-加速),无需网络直接玩。
- 大模型部署加速方法简单总结(大模型 ai)
- 安徽医大第一医院应用VitaFlow Liberty(R)Flex为患者焕然一“心”
- 300 多行代码搞定微信 8.0 的「炸」「裂」特效!
- 让div填充屏幕剩余高度的方法(div填充20px)
- css之div内容居中(css中div怎么居中)
- 使用uniapp开发小程序遇到的一些问题及解决方法
- 微信小程序主页面排版(怎样设置小程序的排版)
- Vue动态组件的实践与原理探究(vue动态组件component原理)
- 【HarmonyOS Next之旅】兼容JS的类Web开发(四) -> tabs
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML常用标签 (29)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)
- HTML button formtarget 属性 (30)
- CSS 水平对齐 (Horizontal Align) (30)