使用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 相关文章推荐
javascript 动态加载 css 方法总结
Jul 11 Javascript
javascript Window及document对象详细整理
Jan 12 Javascript
$.format,jquery.format 使用说明
Jul 13 Javascript
JavaScript检测上传文件大小的方法
Jul 22 Javascript
jQuery实现信息提示框(带有圆角框与动画)效果
Aug 07 Javascript
jQuery Easyui学习之datagrid 动态添加、移除editor
Jan 27 Javascript
D3.js实现柱状图的方法详解
Sep 21 Javascript
微信小程序 tabs选项卡效果的实现
Jan 05 Javascript
Vue 实现点击空白处隐藏某节点的三种方式(指令、普通、遮罩)
Oct 23 Javascript
layui实现数据表格自定义数据项
Oct 26 Javascript
修改Vue打包后的默认文件名操作
Aug 12 Javascript
浅谈vue使用axios的回调函数中this不指向vue实例,为undefined
Sep 21 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代码飞起来的40条小技巧(提升php效率)
2010/04/12 PHP
PHP动态分页函数,PHP开发分页必备啦
2011/11/07 PHP
php cookie使用方法学习笔记分享
2013/11/07 PHP
老生常谈ThinkPHP中的行为扩展和插件(推荐)
2017/05/05 PHP
关于php支持的协议与封装协议总结(推荐)
2017/11/17 PHP
laravel-admin select框默认选中的方法
2019/10/03 PHP
js查找某元素中的所有图片地址的方法
2014/01/16 Javascript
使用ngView配合AngularJS应用实现动画效果的方法
2015/06/19 Javascript
深入探讨前端框架react
2015/12/09 Javascript
js实现弹窗居中的简单实例
2016/10/09 Javascript
js 将input框中的输入自动转化成半角大写(税号输入框)
2017/02/16 Javascript
详谈表单重复提交的三种情况及解决方法
2017/08/16 Javascript
vue better-scroll插件使用详解
2018/01/25 Javascript
jQuery pager.js 插件动态分页功能实例分析
2019/08/02 jQuery
Vue+Element UI+vue-quill-editor富文本编辑器及插入图片自定义
2019/08/20 Javascript
python k-近邻算法实例分享
2014/06/11 Python
通过数据库对Django进行删除字段和删除模型的操作
2015/07/21 Python
python机器学习之贝叶斯分类
2018/03/26 Python
Python Selenium Cookie 绕过验证码实现登录示例代码
2018/04/10 Python
python无限生成不重复(字母,数字,字符)组合的方法
2018/12/04 Python
pandas ix &iloc &loc的区别
2019/01/10 Python
python使用参数对嵌套字典进行取值的方法
2019/04/26 Python
python实现树的深度优先遍历与广度优先遍历详解
2019/10/26 Python
python list数据等间隔抽取并新建list存储的例子
2019/11/27 Python
python多维数组分位数的求取方式
2020/03/03 Python
HTML5 canvas基本绘图之绘制阴影效果
2016/06/27 HTML / CSS
便携式太阳能系统的创新者:GOAL ZERO
2018/02/04 全球购物
泰国演唱会订票网站:StubHub泰国
2018/02/26 全球购物
英国家居用品和床上用品零售商:P&B Home
2020/01/16 全球购物
Ibatis的核心配置文件都有什么
2014/09/08 面试题
广告学专业毕业生自荐信
2013/09/24 职场文书
艺术设计专业个人求职信
2014/04/10 职场文书
读群众路线的心得体会
2014/09/03 职场文书
2015年高校教师个人工作总结
2015/05/25 职场文书
魂断蓝桥观后感
2015/06/10 职场文书
美国运营商 T-Mobile 以 117.83Mb/s 的速度排第一位
2022/04/21 数码科技