使用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 相关文章推荐
另类调用flash无须激活的方法
Dec 27 Javascript
JavaScript实现在页面间传值的方法
Apr 07 Javascript
jQuery切换所有复选框选中状态的方法
Jul 02 Javascript
JavaScript简单修改窗口大小的方法
Aug 03 Javascript
详谈javascript异步编程
Feb 21 Javascript
angular forEach方法遍历源码解读
Jan 25 Javascript
canvas的神奇用法
Feb 03 Javascript
js读取json文件片段中的数据实例
Mar 09 Javascript
javascript数据结构之串的概念与用法分析
Apr 12 Javascript
Angular2.js实现表单验证详解
Jun 23 Javascript
vue路由跳转传参数的方法
May 06 Javascript
js实现缓动动画
Nov 25 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简单静态页生成过程
2008/03/27 PHP
ThinkPHP后台首页index使用frameset时的注意事项分析
2014/08/22 PHP
php使用$_POST或$_SESSION[]向js函数传参
2014/09/16 PHP
php格式化电话号码的方法
2015/04/24 PHP
php获取从百度、谷歌等搜索引擎进入网站关键词的方法
2015/07/08 PHP
jQuery Jcrop插件实现图片选取功能
2011/11/23 Javascript
jQuery把表单元素变为json对象
2013/11/06 Javascript
解析jquery中的ajax缓存问题
2013/12/19 Javascript
jquery 字符串切割函数substring的用法说明
2014/02/11 Javascript
jQuery中ajax的load()方法用法实例
2014/12/26 Javascript
JavaScript使用concat连接数组的方法
2015/04/06 Javascript
jQuery实现下拉框功能实例代码
2016/05/06 Javascript
浅析Node.js实现HTTP文件下载
2016/08/05 Javascript
jquery购物车结算功能实现方法
2020/10/29 Javascript
vue 中filter的多种用法
2018/04/26 Javascript
解决vue-cli项目打包出现空白页和路径错误的问题
2018/09/04 Javascript
JS函数进阶之prototy用法实例分析
2020/01/15 Javascript
jQuery实现滑动开关效果
2020/08/02 jQuery
Flask框架学习笔记(一)安装篇(windows安装与centos安装)
2014/06/25 Python
Python实现的FTP通信客户端与服务器端功能示例
2018/03/28 Python
Python列表切片操作实例总结
2019/02/19 Python
python爬虫增加访问量的方法
2019/08/22 Python
python实现计算器功能
2019/10/31 Python
Python操作MongoDb数据库流程详解
2020/03/05 Python
PHP基于phpqrcode类库生成二维码过程解析
2020/05/28 Python
Python 按比例获取样本数据或执行任务的实现代码
2020/12/03 Python
英国泽西岛植物:Jersey Plants Direct
2019/08/07 全球购物
英国森林假期:Forest Holidays
2021/01/01 全球购物
长曲棍球装备:Lacrosse Monkey
2020/12/02 全球购物
幼儿园庆六一活动方案
2014/03/06 职场文书
舞蹈专业大学生职业规划范文
2014/03/12 职场文书
党员查摆剖析材料
2014/10/10 职场文书
写给消防战士们的一封慰问信
2019/10/07 职场文书
spring项目中切面及AOP的使用方法
2021/06/26 Java/Android
MySQL中存储时间的最佳实践指南
2021/07/01 MySQL
一次Mysql update sql不当引起的生产故障记录
2022/04/01 MySQL