使用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 相关文章推荐
js中将多个语句写成一个语句的两种方法小结
Dec 08 Javascript
Javascript 实用小技巧
Apr 07 Javascript
基于jQuery的图片剪切插件
Aug 03 Javascript
jquery任意位置浮动固定层插件用法实例
May 29 Javascript
浅析JavaScript中的事件机制
Jun 04 Javascript
jQuery UI库中dialog对话框功能使用全解析
Apr 23 Javascript
vue.js学习笔记:如何加载本地json文件
Jan 17 Javascript
JS利用正则表达式实现简单的密码强弱判断实例
Jun 16 Javascript
angular多语言配置详解
May 16 Javascript
在 Vue 中编写 SVG 图标组件的方法
Feb 24 Javascript
vue中路由跳转不计入history的操作
Sep 21 Javascript
如何管理Vue中的缓存页面
Feb 06 Vue.js
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
PHP4和PHP5共存于一系统
2006/11/17 PHP
PHP实现时间轴函数代码
2011/10/08 PHP
php中将字符串转为HTML的实体引用的一个类
2013/02/03 PHP
PHP中鲜为人知的10个函数
2014/02/28 PHP
php数组去除空值函数分享
2015/02/02 PHP
PHP实现Javascript中的escape及unescape函数代码分享
2015/02/10 PHP
PHP列出MySQL中所有数据库的方法
2015/03/12 PHP
PHP处理Ajax请求与Ajax跨域问题
2017/02/13 PHP
jQuery中的bind绑定事件与文本框改变事件的临时解决方法
2010/08/13 Javascript
各浏览器对click方法的支持差异小结
2011/07/31 Javascript
For循环中分号隔开的3部分的执行顺序探讨
2014/05/27 Javascript
jQuery设置和获取HTML、文本和值示例
2014/07/08 Javascript
网页运行时提示对象不支持abigimage属性或方法
2014/08/10 Javascript
BootStrap扔进Django里的方法详解
2016/05/13 Javascript
JS 日期与时间戮相互转化的简单实例
2016/06/22 Javascript
用nodejs的实现原理和搭建服务器(动态)
2016/08/10 NodeJs
jQuery flip插件实现的翻牌效果示例【附demo源码下载】
2016/09/20 Javascript
js获取浏览器和屏幕的各种宽度高度
2017/02/22 Javascript
Angular2 http jsonp的实例详解
2017/08/31 Javascript
详解在express站点中使用ejs模板引擎
2017/09/21 Javascript
详解nvm管理多版本node踩坑
2019/07/26 Javascript
vue实现输入框自动跳转功能
2020/05/20 Javascript
JavaScript设计模式--简单工厂模式实例分析【XHR工厂案例】
2020/05/23 Javascript
JS实现简单打字测试
2020/06/24 Javascript
浅析python递归函数和河内塔问题
2017/04/18 Python
python3.x实现发送邮件功能
2018/05/22 Python
django echarts饼图数据动态加载的实例
2019/08/12 Python
浅谈python opencv对图像颜色通道进行加减操作溢出
2020/06/03 Python
Python中操作各种多媒体,视频、音频到图片的代码详解
2020/06/04 Python
Prototype如何为一个Ajax添加一个参数
2015/12/06 面试题
商务英语应届生自我鉴定
2013/12/08 职场文书
平面网站制作专科生的自我评价分享
2013/12/11 职场文书
房地产销售计划书
2014/01/10 职场文书
合理化建议书
2015/02/04 职场文书
反腐倡廉学习心得体会范文
2015/08/15 职场文书
css3 文字断裂效果
2022/04/22 HTML / CSS