使用Karma做vue组件单元测试的实现


Posted in Javascript onJanuary 16, 2020

养成良好的编码习惯,一个合格的程序员需要掌握一些编写单元测试的能力。单元测试也可以整体上提升我们的代码质量,这里介绍下 VUE 组件的单元测试。

如果想直接通过 Demo 学习,可以跳过下面的内容,点击这里下载示例

技术栈

  • @vue/test-utils[1.0.0-beta.30]
  • istanbul-instrumenter-loader[3.0.1]
  • karma[4.4.1]
  • karma-chrome-launcher[3.1.0]
  • karma-mocha[1.3.0]
  • karma-sourcemap-loader[0.3.7]
  • karma-coverage-istanbul-reporter[2.1.1]
  • karma-webpack[4.0.2]
  • webpack[4.41.5]

定义配置文件

karma.conf.js 文件用于 karma 的配置,使用 node_modules/.bin/karma init 命令创建该文件,我们定义如下配置:

// Karma configuration

const webpackConfig = require('./config/webpack.test.config.js')

module.exports = function(config) {
 config.set({

  // base path that will be used to resolve all patterns (eg. files, exclude)
  basePath: '.',

  // frameworks to use
  // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
  frameworks: [ 'mocha' ],

  // list of files / patterns to load in the browser
  files: [
   'test/**/*.spec.js'
  ],

  // preprocess matching files before serving them to the browser
  // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
  preprocessors: {
   'test/**/*.spec.js': [ 'webpack', 'sourcemap' ]
  },

  // webpack config
  webpack: webpackConfig,

  webpackMiddleware: {
   stats: 'errors-only'
  },

  // web server port
  port: 9876,

  // enable / disable colors in the output (reporters and logs)
  colors: true,

  // level of logging
  // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
  logLevel: config.LOG_INFO,

  // enable / disable watching file and executing tests whenever any file changes
  autoWatch: true,

  // start these browsers
  // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
  browsers: [ 'Chrome' ],

  // Continuous Integration mode
  // if true, Karma captures browsers, runs the tests and exits
  singleRun: false,

  // Concurrency level
  // how many browser should be started simultaneous
  concurrency: Infinity
 })
}
  1. 设置 frameworks 为 ['mocha'],即使用 mocha 测试框架
  2. 设置 files 为 ['test/**/*.spec.js'],即对 test 目录下所有的后缀为 .spec.js 文件测试
  3. 设置 preprocessors 为 {'**/*.spec.js': ['webpack', 'sourcemap']},即使用 webpack,sourcemap 对所有的测试文件进行 webpack 打包
  4. 设置 browsers 为 Chrome,即使用 Chrome 浏览器作为测试浏览器

编写测试用例

详细的关于 @vue/test-utils 用法,查看 https://vue-test-utils.vuejs.org/zh/

import { expect } from 'chai'
import { shallowMount } from '@vue/test-utils'
import Header from '../src/components/Header'

describe('Header', () => {
 const wrapper = shallowMount(Header)
 const header = wrapper.find('header')
 const h1 = wrapper.find('h1')

 it('有 header 标签', () => {
  expect(header.exists()).to.be.true
 })

 it('有 h1 标签', () => {
  expect(h1.exists()).to.be.true
 })

 it('h1 的文案为“VUE 单页模版”', () => {
  expect(h1.text()).to.equal('VUE 单页模版')
 })

 it('h1 标签在 header 标签中', () => {
  expect(header.contains('h1')).to.be.true
 })
})

这里我引用 vue-single-page 的 Header 组件测试用例

  1. 首先通过 shallowMount 获取 wrapper
  2. 使用 chai 断言库编写相关的测试用例

运行结果

i 「wdm」: Compiled successfully.
15 01 2020 18:28:13.799:INFO [karma-server]: Karma v4.4.1 server started at http://0.0.0.0:9876/
15 01 2020 18:28:13.813:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
15 01 2020 18:28:13.820:INFO [launcher]: Starting browser Chrome
15 01 2020 18:28:17.075:INFO [Chrome 79.0.3945 (Windows 10.0.0)]: Connected on socket PUKPz4iBuFzeVNSsAAAA with id 91716917
TOTAL: 4 SUCCESS

可以看到我们的单元测试已经通过了

测试覆盖率报告

测试完成后,我们需要查看测试覆盖率报告。这需要在 webpack.test.config.js 和 karma.conf.js 中做一些配置修改

webpack.test.config.js

const merge = require('webpack-merge')
const path = require('path')
const webpackCommonConfig = require('./webpack.common.config')

const testConfig = {
 devtool: 'inline-source-map',
 mode: 'none',
 module: {
  rules: [
   {
    test: /\.spec.js$/i,
    enforce: 'pre',
    use: [
     {
      loader: 'istanbul-instrumenter-loader',
      options: {
       esModules: true
      }
     }
    ]
   }
  ]
 }
}

module.exports = merge(webpackCommonConfig, testConfig)

添加一个优先执行的编译 .spec.js 文件的 rules,loader 使用 istanbul-instrumenter-loader 并开启 esModules 模式

karma.conf.js

module.exports = function(config) {
 config.set({
 
  // ...
  
  coverageIstanbulReporter: {
   reports: [ 'html', 'text' ],
   fixWebpackSourcePaths: true
  },
  
  reporters: [ 'coverage-istanbul' ]

  //...
  
 })
}
  1. 设置 reporters 为 [ 'coverage-istanbul' ],即使用 coverage-istanbul reporters
  2. coverageIstanbulReporter 配置项用于设置 coverage-istanbul 的参数,详细的参数可以参考 这里

运行结果

再次执行单元测试,我们会看到测试覆盖率的相关信息

----------------|----------|----------|----------|----------|-------------------|
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------------|----------|----------|----------|----------|-------------------|
All files    |   100 |   100 |   100 |   100 |          |
 Header.spec.js |   100 |   100 |   100 |   100 |          |
----------------|----------|----------|----------|----------|-------------------|

也可以通过生成到 coverage 目录下的网页文件,在浏览器中查看

使用Karma做vue组件单元测试的实现

参考资料

https://vue-test-utils.vuejs.org/zh/
https://github.com/mattlewis92/karma-coverage-istanbul-reporter

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery AJAX 调用WebService实现代码
Mar 24 Javascript
ejs v9 javascript模板系统
Mar 21 Javascript
JS脚本实现动态给标签控件添加事件的方法
Jun 02 Javascript
vue2 前端搜索实现示例
Feb 26 Javascript
Angular @HostBinding()和@HostListener()用法
Mar 05 Javascript
浅谈JavaScript 代码整洁之道
Oct 23 Javascript
vue下拉菜单组件(含搜索)的实现代码
Nov 25 Javascript
jquery层次选择器的介绍
Jan 18 jQuery
vue19 组建 Vue.extend component、组件模版、动态组件 的实例代码
Apr 04 Javascript
vue中使用 pako.js 解密 gzip加密字符串的方法
Jun 10 Javascript
js实现一个简易计算器
Mar 30 Javascript
layui radio单选限制下一个radio单选的实例
Sep 03 Javascript
js实现div色块拖动录制
Jan 16 #Javascript
微信小程序实现二维码签到考勤系统
Jan 16 #Javascript
解决vue+ element ui 表单验证有值但验证失败问题
Jan 16 #Javascript
JavaScript实现简单的计算器
Jan 16 #Javascript
js面向对象之实现淘宝放大镜
Jan 15 #Javascript
js实现简单的打印表格
Jan 15 #Javascript
js实现图片实时时钟
Jan 15 #Javascript
You might like
PHP支持多种格式图片上传(支持jpg、png、gif)
2011/11/03 PHP
PHP使用CURL模拟登录的方法
2015/07/08 PHP
详解PHP中array_rand函数的使用方法
2016/09/11 PHP
PHP生成唯一ID之SnowFlake算法
2016/12/17 PHP
js计数器代码
2006/11/04 Javascript
input 输入框内的输入事件详细分析
2010/03/17 Javascript
jquery 图片截取工具jquery.imagecropper.js
2010/04/09 Javascript
关于hashchangebroker和statehashable的补充文档
2011/08/08 Javascript
JS重要知识点小结
2011/11/06 Javascript
Javascript基础教程之数据类型转换
2015/01/18 Javascript
ECMAScript6块级作用域及新变量声明(let)
2015/06/12 Javascript
jQuery插件支持同一页面被多次调用
2016/02/14 Javascript
JavaScript实现设计模式中的单例模式的一些技巧总结
2016/05/17 Javascript
微信+angularJS的SPA应用中用router进行页面跳转,jssdk校验失败问题解决
2016/09/09 Javascript
javascript创建对象的3种方法
2016/11/02 Javascript
javascript实现获取图片大小及图片等比缩放的方法
2016/11/24 Javascript
JavaScript使用原型和原型链实现对象继承的方法详解
2017/04/05 Javascript
在vue项目中引用Iview的方法
2018/09/14 Javascript
Node.js中Koa2在控制台输出请求日志的方法示例
2019/05/02 Javascript
原生Vue 实现右键菜单组件功能
2019/12/16 Javascript
分析python服务器拒绝服务攻击代码
2014/01/16 Python
Python同时向控制台和文件输出日志logging的方法
2015/05/26 Python
python 全局变量的import机制介绍
2017/09/07 Python
python使用logging模块发送邮件代码示例
2018/01/18 Python
Python使用matplotlib绘图无法显示中文问题的解决方法
2018/03/14 Python
基于Django集成CAS实现流程详解
2020/11/28 Python
HTML5微信播放全屏问题的解决方法
2017/03/09 HTML / CSS
使用HTML5加载音频和视频的实现代码
2020/11/30 HTML / CSS
社区庆中秋节活动方案
2014/02/07 职场文书
入党积极分子学习两会心得体会范文
2014/03/17 职场文书
保证书格式范文
2014/04/28 职场文书
先进事迹材料范文
2014/12/29 职场文书
2015年春训学习心得体会范文
2015/03/09 职场文书
党校培训学习心得体会
2016/01/06 职场文书
教师法制教育培训学习心得体会
2016/01/14 职场文书
将Python代码打包成.exe可执行文件的完整步骤
2021/05/12 Python