使用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 相关文章推荐
禁止F5等快捷键的JS代码
Mar 06 Javascript
js中widow.open()方法使用详解
Jul 30 Javascript
node.js中的events.EventEmitter.listenerCount方法使用说明
Dec 08 Javascript
jquery实现点击变换导航样式的方法
Aug 31 Javascript
jQuery鼠标悬浮链接弹出跟随图片实例代码
Jan 08 Javascript
浅谈js中用$(#ID)来作为选择器的问题(id重复的时候)
Feb 14 Javascript
jQuery时间验证和转换为标准格式的时间格式
Mar 06 Javascript
jQuery Validate 校验多个相同name的方法
May 18 jQuery
浅谈Webpack 是如何加载模块的
May 24 Javascript
JavaScript数据结构与算法之检索算法示例【二分查找法、计算重复次数】
Feb 22 Javascript
微信小程序学习总结(二)样式、属性、模板操作分析
Jun 04 Javascript
原生js实现html手机端城市列表索引选择城市
Jun 24 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
thinkphp3.2嵌入百度编辑器ueditor的实例代码
2017/07/13 PHP
PHP中PCRE正则解析代码详解
2019/04/26 PHP
JQuery 遮罩层实现(mask)实现代码
2010/01/09 Javascript
Web开发者必备的12款超赞jQuery插件
2010/12/03 Javascript
获取内联和链接中的样式(js代码)
2013/04/11 Javascript
js同比例缩放图片的小例子
2013/10/30 Javascript
JS应用正则表达式转换大小写示例
2014/09/18 Javascript
jQuery实现两款有动画功能的导航菜单代码
2015/09/16 Javascript
基于javascript实现checkbox复选框实例代码
2016/01/28 Javascript
js闭包引起的事件注册问题介绍
2016/03/29 Javascript
jQuery事件绑定on()与弹窗实现代码
2016/04/28 Javascript
批量下载对路网图片并生成html的实现方法
2016/06/07 Javascript
jQuery+ajax实现实用的点赞插件代码
2016/07/06 Javascript
jQuery实现表格与ckeckbox的全选与单选功能
2016/11/24 Javascript
探究react-native 源码的图片缓存问题
2017/08/24 Javascript
Postman的下载及安装教程详解
2018/10/16 Javascript
JS中注入eval, Function等系统函数截获动态代码
2019/04/03 Javascript
使用Vue父子组件通信实现todolist的功能示例代码
2019/04/11 Javascript
Openlayers实现距离面积测量
2020/09/28 Javascript
[00:32]10月24、25日 辉夜杯外卡赛附加赛开赛!
2015/10/23 DOTA
pycharm 使用心得(三)Hello world!
2014/06/05 Python
Python读写ini文件的方法
2015/05/28 Python
遗传算法python版
2018/03/19 Python
通过Py2exe将自己的python程序打包成.exe/.app的方法
2018/05/26 Python
python利用7z批量解压rar的实现
2019/08/07 Python
使用python绘制温度变化雷达图
2019/10/18 Python
解决python web项目意外关闭,但占用端口的问题
2019/12/17 Python
python列表的逆序遍历实现
2020/04/20 Python
python制作微博图片爬取工具
2021/01/16 Python
宝拉珍选英国官网:Paula’s Choice英国
2019/05/29 全球购物
优秀班集体获奖感言
2014/02/03 职场文书
会计专业毕业自荐书范文
2014/02/08 职场文书
小学运动会班级口号
2014/06/09 职场文书
超市开店计划书
2014/09/15 职场文书
教师查摆问题自查报告
2014/10/11 职场文书
2015年秋学期教研工作总结
2015/10/14 职场文书