使用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 相关文章推荐
基于jsTree的无限级树JSON数据的转换代码
Jul 27 Javascript
更快的异步执行(setTimeout多浏览器)
Aug 12 Javascript
解决angular的$http.post()提交数据时后台接收不到参数值问题的方法
Dec 10 Javascript
深入浅出ES6新特性之函数默认参数和箭头函数
Aug 01 Javascript
javascript实现table单元格点击展开隐藏效果(实例代码)
Apr 10 Javascript
js学习总结之DOM2兼容处理重复问题的解决方法
Jul 27 Javascript
Bootstrap Table实现定时刷新数据的方法
Aug 13 Javascript
解决vue 界面在苹果手机上滑动点击事件等卡顿问题
Nov 27 Javascript
js中怎么判断两个字符串相等的实例
Jan 17 Javascript
如何在Angular应用中创建包含组件方法示例
Mar 23 Javascript
node将geojson转shp返回给前端的实现方法
May 29 Javascript
使用p5.js临摹动态图形
Oct 23 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分页类代码
2013/04/02 PHP
鼠标移动到一张图片时变为另一张图片
2006/12/05 Javascript
MooTools 1.2中的Drag.Move来实现拖放
2009/09/15 Javascript
图像替换新技术 状态域方法
2010/01/28 Javascript
EXTJS FORM HIDDEN TEXTFIELD 赋值 使用value不好用的问题
2011/04/16 Javascript
JS模拟按钮点击功能的方法
2015/12/22 Javascript
详解Javascript中的Object对象
2016/02/28 Javascript
jQuery模拟select实现下拉菜单功能
2016/06/20 Javascript
详解handlebars+require基本使用方法
2016/12/21 Javascript
jQuery使用DataTable实现删除数据后重新加载功能
2017/02/27 Javascript
jQuery中table数据的值拷贝和拆分
2017/03/19 Javascript
Angular2中select用法之设置默认值与事件详解
2017/05/07 Javascript
详解如何在 vue 项目里正确地引用 jquery 和 jquery-ui的插件
2017/06/01 jQuery
vue实现跳转接口push 转场动画示例
2019/11/01 Javascript
vue动态路由:路由参数改变,视图不更新问题的解决
2019/11/05 Javascript
基于jQuery实现挂号平台首页源码
2020/01/06 jQuery
vue@cli3项目模板怎么使用public目录下的静态文件
2020/07/07 Javascript
js实现碰撞检测
2021/01/29 Javascript
实例讲解python函数式编程
2014/06/09 Python
Python使用设计模式中的责任链模式与迭代器模式的示例
2016/03/02 Python
利用django如何解析用户上传的excel文件
2017/07/24 Python
Python读取文件内容的三种常用方式及效率比较
2017/10/07 Python
Python对多属性的重复数据去重实例
2018/04/18 Python
python xpath获取页面注释的方法
2019/01/14 Python
python 监听salt job状态,并任务数据推送到redis中的方法
2019/01/14 Python
python保留格式汇总各部门excel内容的实现思路
2020/06/01 Python
益模软件Java笔试题
2012/03/27 面试题
如何反序的迭代一个序列?how do I iterate over a sequence in reverse order
2012/02/04 面试题
SOA的常见陷阱或者误解是什么
2014/10/05 面试题
村长贪污检举信
2014/04/04 职场文书
三年级班级文化建设方案
2014/05/04 职场文书
工作疏忽、懈怠的检讨书
2014/09/11 职场文书
2015年社区民政工作总结
2015/04/21 职场文书
2019年工作总结范文
2019/05/21 职场文书
SQLServer 错误: 15404,无法获取有关 Windows NT 组/用户 WIN-8IVSNAQS8T7\Administrator 的信息
2021/06/30 SQL Server
海弦WR-800F
2022/04/05 无线电