使用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创建对象的几种常用方式小结(推荐)
Oct 24 Javascript
JQuery实现用户名无刷新验证的小例子
Mar 22 Javascript
js实现图片轮换效果代码
Apr 16 Javascript
JS中使用apply、bind实现为函数或者类传入动态个数的参数
Apr 26 Javascript
AJAX实现瀑布流触发分页与分页触发瀑布流的方法
May 23 Javascript
jQuery为某个div加入行样式
Jun 09 jQuery
js实现简单数字变动效果
Nov 06 Javascript
浅析前端路由简介以及vue-router实现原理
Jun 01 Javascript
小程序hover-class点击态效果实现
Feb 26 Javascript
基于vue3.0.1beta搭建仿京东的电商H5项目
May 06 Javascript
Node 模块原理与用法详解
May 13 Javascript
vue组件开发之slider组件使用详解
Aug 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邮件类
2007/01/03 PHP
PHP日期时间函数的高级应用技巧
2009/05/16 PHP
PHP中array_slice函数用法实例详解
2014/11/25 PHP
浅谈php7的重大新特性
2015/10/23 PHP
PHP的Yii框架的常用日志操作总结
2015/12/08 PHP
Yii2 中实现单点登录的方法
2018/03/09 PHP
fancybox1.3.1 基于Jquery的插件在IE中图片显示问题
2010/10/01 Javascript
jquery实现盒子下拉效果示例代码
2013/09/12 Javascript
javascript 获取iframe里页面中元素值的方法
2014/02/17 Javascript
Javascript WebSocket使用实例介绍(简明入门教程)
2014/04/16 Javascript
一个仿糯米弹框效果demo
2014/07/22 Javascript
Javascript毫秒数用法实例
2015/02/05 Javascript
使用AngularJS编写较为优美的JavaScript代码指南
2015/06/19 Javascript
JavaScript实现标题栏文字轮播效果代码
2015/10/24 Javascript
jQuery css() 方法动态修改CSS属性
2016/09/25 Javascript
微信小程序网络请求wx.request详解及实例
2017/05/18 Javascript
Angular 4中如何显示内容的CSS样式示例代码
2017/11/06 Javascript
es6在react中的应用代码解析
2017/11/08 Javascript
Vuejs 实现简易 todoList 功能 与 组件实例代码
2018/09/10 Javascript
详解React中合并单元格的正确写法
2019/01/08 Javascript
node实现mock-plugin中间件的方法
2019/12/25 Javascript
[02:40]DOTA2殁境神蚀者 英雄基础教程
2013/11/26 DOTA
[01:17]辉夜杯战队访谈宣传片—EHOME
2015/12/25 DOTA
[52:31]VP vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
解决python通过cx_Oracle模块连接Oracle乱码的问题
2018/10/18 Python
对django中foreignkey的简单使用详解
2019/07/28 Python
python 申请内存空间,用于创建多维数组的实例
2019/12/02 Python
HTML5组件Canvas实现图像灰度化(步骤+实例效果)
2013/04/22 HTML / CSS
智利最大的网上商店:Linio智利
2016/11/24 全球购物
美国真皮手袋品牌:GiGi New York
2017/03/10 全球购物
德国药房apodiscounter中文官网:德国排名前三的网上药店
2019/06/03 全球购物
什么是跨站脚本攻击
2014/12/11 面试题
Ajxa常见问题都有哪些
2014/03/26 面试题
信息技术专业大学生个人的自我评价
2013/10/05 职场文书
学校四风对照检查材料
2014/08/28 职场文书
python的变量和简单数字类型详解
2021/09/15 Python