时间:2021-05-25
在使用vue-cli创建项目的时候,会提示要不要安装单元测试和e2e测试。既然官方推荐我们使用这两个测试框架,那么我们就动手去学习实践一下他们吧。
简介
Karma
Karma是一个基于Node.js的JavaScript测试执行过程管理工具(Test Runner)。该工具在Vue中的主要作用是将项目运行在各种主流Web浏览器进行测试。
换句话说,它是一个测试工具,能让你的代码在浏览器环境下测试。需要它的原因在于,你的代码可能是设计在浏览器端执行的,在node环境下测试可能有些bug暴露不出来;另外,浏览器有兼容问题,karma提供了手段让你的代码自动在多个浏览器(chrome,firefox,ie等)环境下运行。如果你的代码只会运行在node端,那么你不需要用karma。
Mocha
Mocha是一个测试框架,在vue-cli中配合chai断言库实现单元测试。
而Chai断言库可以看Chai.js断言库API中文文档,很简单,多查多用就能很快掌握。
我对测试框架的理解
npm run unit 执行过程
Karma
对于Karma,我只是了解了一下它的配置选项。
下面是Vue的karma配置,简单注释了下:
var webpackConfig = require('../../build/webpack.test.conf')module.exports = function (config) { config.set({ // 浏览器 browsers: ['PhantomJS'], // 测试框架 frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'], // 测试报告 reporters: ['spec', 'coverage'], // 测试入口文件 files: ['./index.js'], // 预处理器 karma-webpack preprocessors: { './index.js': ['webpack', 'sourcemap'] }, // Webpack配置 webpack: webpackConfig, // Webpack中间件 webpackMiddleware: { noInfo: true }, // 测试覆盖率报告 // https://github.com/karma-runner/karma-coverage/blob/master/docs/configuration.md coverageReporter: { dir: './coverage', reporters: [ { type: 'lcov', subdir: '.' }, { type: 'text-summary' } ] } })}Mocha和chai
我们看下官方的例子(都用注释来解释代码意思了):
import Vue from 'vue' // 导入Vue用于生成Vue实例import Hello from '@/components/Hello' // 导入组件// 测试脚本里面应该包括一个或多个describe块,称为测试套件(test suite)describe('Hello.vue', () => { // 每个describe块应该包括一个或多个it块,称为测试用例(test case) it('should render correct contents', () => { const Constructor = Vue.extend(Hello) // 获得Hello组件实例 const vm = new Constructor().$mount() // 将组件挂在到DOM上 //断言:DOM中class为hello的元素中的h1元素的文本内容为Welcome to Your Vue.js App expect(vm.$el.querySelector('.hello h1').textContent) .to.equal('Welcome to Your Vue.js App') })})需要知道的知识点:
了解一下 describe 的钩子(生命周期)
实践
上面简单介绍了单元测试的用法,下面来动手在Vue中进行单元测试!
util.js
从Vue官方的demo可以看出,对于Vue的单元测试我们需要将组件实例化为一个Vue实例,有时还需要挂载到DOM上。
const Constructor = Vue.extend(Hello) // 获得Hello组件实例 const vm = new Constructor().$mount() // 将组件挂载到DOM上以上写法只是简单的获取组件,有时候我们需要传递props属性、自定义方法等,还有可能我们需要用到第三方UI框架。所以以上写法非常麻烦。
这里推荐Element的单元测试工具脚本Util.js,它封装了Vue单元测试中常用的方法。下面demo也是根据该 Util.js来写的。
这里简单注释了下各方法的用途。
示例一
示例一中我们测试了 Hello 组件的各种元素的数据,学习 util.js 的 destroyVM 和 createTest 方法的用法以及如何获取目标元素进行测试。获取DOM元素的方式可查看DOM 对象教程。
Hello.vue
<template> <div class="hello"> <h1 class="hello-title">{{ msg }}</h1> <h2 class="hello-content">{{ content }}</h2> </div></template><script>export default { name: 'hello', props: { content: String }, data () { return { msg: 'Welcome!' } }}</script>Hello.spec.js
import { destroyVM, createTest } from '../util'import Hello from '@/components/Hello'describe('Hello.vue', () => { let vm afterEach(() => { destroyVM(vm) }) it('测试获取元素内容', () => { vm = createTest(Hello, { content: 'Hello World' }, true) expect(vm.$el.querySelector('.hello h1').textContent).to.equal('Welcome!') expect(vm.$el.querySelector('.hello h2').textContent).to.have.be.equal('Hello World') }) it('测试获取Vue对象中数据', () => { vm = createTest(Hello, { content: 'Hello World' }, true) expect(vm.msg).to.equal('Welcome!') // Chai的语言链是无意义的,可以随便写。如下: expect(vm.content).which.have.to.be.that.equal('Hello World') }) it('测试获取DOM中是否存在某个class', () => { vm = createTest(Hello, { content: 'Hello World' }, true) expect(vm.$el.classList.contains('hello')).to.be.true const title = vm.$el.querySelector('.hello h1') expect(title.classList.contains('hello-title')).to.be.true const content = vm.$el.querySelector('.hello-content') expect(content.classList.contains('hello-content')).to.be.true })})输出结果
Hello.vue
√ 测试获取元素内容
√ 测试获取Vue对象中数据
√ 测试获取DOM中是否存在某个class
示例二
示例二中我们使用 createTest 创建测试组件测试点击事件,用 createVue 创建Vue示例对象测试组件 Click 的使用。这里主要可以看下到 createVue 方法的使用。
Click.vue
<template> <div> <span class="init-num">初始值为{{ InitNum }}</span><br> <span class="click-num">点击了{{ ClickNum }}次</span><br> <span class="result-num">最终结果为{{ ResultNum }}</span><br> <button @click="add">累加{{ AddNum }}</button> </div></template><script>export default { name: 'Click', props: { AddNum: { type: Number, default: 1 }, InitNum: { type: Number, default: 1 } }, data () { return { ClickNum: 0, ResultNum: 0 } }, mounted () { this.ResultNum = this.InitNum }, methods: { add () { this.ResultNum += this.AddNum this.ClickNum++ this.$emit('result', { ClickNum: this.ClickNum, ResultNum: this.ResultNum }) } }}</script>Click.spec.js
import { destroyVM, createTest, createVue } from '../util'import Click from '@/components/Click'describe('click.vue', () => { let vm afterEach(() => { destroyVM(vm) }) it('测试按钮点击事件', () => { vm = createTest(Click, { AddNum: 10, InitNum: 11 }, true) let buttonElm = vm.$el.querySelector('button') buttonElm.click() buttonElm.click() buttonElm.click() // setTimeout 的原因 // 在数据改变之后,界面的变化会有一定延时。不用timeout有时候会发现界面没有变化 setTimeout(done => { expect(vm.ResultNum).to.equal(41) expect(vm.$el.querySelector('.init-num').textContent).to.equal('初始值为11') expect(vm.$el.querySelector('.click-num').textContent).to.equal('点击了3次') expect(vm.$el.querySelector('.result-num').textContent).to.equal('最终结果为41') done() }, 100) }) it('测试创建Vue对象', () => { let result vm = createVue({ template: ` <click @click="handleClick"></click> `, props: { AddNum: 10, InitNum: 11 }, methods: { handleClick (obj) { result = obj } }, components: { Click } }, true) vm.$el.click() vm.$nextTick(done => { expect(result).to.be.exist expect(result.ClickNum).to.equal(1) expect(result.ResultNum).to.be.equal(21) done() })})输出结果
click.vue
√ 测试按钮点击事件
√ 测试创建Vue对象
其他
所有示例代码都放Github仓库中便于查看。如果想查看更多好的测试用例,建议配合 Util.js 看一下 Element 的单元测试脚本的写法,里面有很多测试脚本可以供我们学习。作为被广大Vue用户使用的UI组件库,测试脚本肯定也写很很不错的~甚至可以将这些脚本照抄一遍,相信这会对学习Vue组件的单元测试有很大帮助。
下面是本人看Element单元测试的笔记,供参考。
Util.js 方法包含了大多数Vue组件化的测试需求。
vm.$el vm.$nextTick 和 vm.$ref 都是在测试过程中比较常用的一些Vue语法糖。
需要注意: vm.$nextTick 方法是异步的,所以需要在里面使用done方法。
异步断言,方法参数需要是 _ 或者 done
大多数时候查询元素通过 querySelector 方法查询class获得
大多数情况下查询是否存在某个Class通过 classList.contains 方法获得,查找的结果为 true 或 false
异步测试必须以 done() 方法结尾。setTimeout 和 vm.$nextTick 是常用的异步测试。
实现按钮点击:通过获取按钮元素 btn,执行 btn.click() 方法实现。
由于 Vue 进行异步更新DOM 的情况,一些依赖DOM更新结果的断言必须在 Vue.nextTick 回调中进行。
Vue.js学习系列项目地址:https://github.com/violetjack/VueStudyDemos
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
书接上文,karma+webpack搭建vue单元测试环境介绍了vue单元测试环境搭建及查看源文件的测试覆盖覆盖率。今天来说一下vue单元测试思路和case的写
一、写在前面这篇文章的代码使用karma,mocha,chai,sinon-chai配合Vue的实例属性进行单元测试二、全局的组件的坑由于我的g-icon是全局
安装必要的包nodejs的单元测试最常用的是使用mocha包。首先确保你本地安装nodejs,之后按照mocha包。npminstallmocha-g然后还需要
为什么要进行单元测试?单元测试保证局部代码的质量单元测试改良项目代码的整体结构单元测试降低测试、维护升级的成本单元测试使开发过程适应频繁变化的需求单元测试有助于
养成良好的编码习惯,一个合格的程序员需要掌握一些编写单元测试的能力。单元测试也可以整体上提升我们的代码质量,这里介绍下VUE组件的单元测试。如果想直接通过Dem