vue项目中jest单元测试

2,529 阅读2分钟

资源

文档网址:Vue Test Utils

参考学习的单测项目:github.com/holylovelqq…

jest单元测试好文:

一些文章:

blog.csdn.net/sinat_33312…

www.imooc.com/article/254…

zhuhuix.blog.csdn.net/article/det…

jestjs.io/zh-Hans/doc…

molunerfinn.com/Use-Jest-To…

juejin.cn/post/684490…

juejin.cn/post/686547…

medium.com/@lachlanmil…

zhuanlan.zhihu.com/p/88875020

jestjs.io/zh-Hans/doc…

安装

在vue项目中安装jest和vue-test-utils(文档地址:vue-test-utils.vuejs.org/zh/) 安装成功后会生成tests文件夹,测试用例写在tests/unit下,文件以.spec.js后缀名结尾。 package.json中增加script配置:"test:unit": "vue-cli-service test:unit" 用以运行单测环境。 ​

遇到的一些问题及解决方案

  1. image.png

类似问题:

stackoverflow.com/questions/6…

stackoverflow.com/questions/4…

解决办法:

const wrapper = shallowMount(组件, {
  propsData,
  attachTo: document.body
})
  1. store中require.context 问题(vue babel-plugin-require-context-hook)

解决方案:zhuanlan.zhihu.com/p/88875020 按第5点解决

  1. [Vue warn]: Error in data(): "TypeError: Cannot read property 'docBaseUrl' of undefined" 设置configer未起作用

image.png 解决方案:

import { configer } from './xxxxxx.js
import { shallowMount, createLocalVue } from '@vue/test-utils'
const localVue = createLocalVue()

// 设置configer
localVue.prototype.configer = configer'
  1. image.png

解决方案:

// jest.config.js 配置文件中排除相关目录
transformIgnorePatterns: ["/node_modules/(?!vue-waterfall2)"]

import { shallowMount, createLocalVue } from '@vue/test-utils'
import waterfall from 'vue-waterfall2'

const localVue = createLocalVue()
localVue.use(waterfall)


  1. image.png

解决方案:

const wrapper = shallowMount(组件, { store, stubs: ['AddContent'] })

配置文件

// 由于某些原因,需要排除某些测试文件
testPathIgnorePatterns: [
  'tests/views/Layout.spec.js',
  'tests/views/Workbench/Workbench.spec.js'
],
 //获取自定义 指定检查所有需要测试的文件  不配置是默认
 collectCoverageFrom: [
   'src/**/*.{js,vue}', // 配置需要测试的文件
   '!src/main.js', // 排除文件及目录
   '!src/plugin/*.js',
   '!**/node_modules/**',
   '!src/assets/**',
   '!tests/**/*.js'
 ],

jest配置

/**
 * @func JEST-配置文件
 * @Author xxx
 * @lastEditor xxx
 * @lastEditTime xxxx-xx-xx
 */

module.exports = {
  moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
  transform: {
      '^.+\\.vue$': 'vue-jest',
      '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
      'jest-transform-stub',
      '^.+\\.jsx?$': 'babel-jest'
  },
  transformIgnorePatterns: ['/node_modules/(?!vue-waterfall2)'], 
  moduleNameMapper: {
      '^@/(.*)$': '<rootDir>/src/$1'
  },
  // 指定snapshot测试的序列化模块
  snapshotSerializers: ['jest-serializer-vue'],
  // 指定测试文件范围
  testMatch: [
      '**/tests/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
  ],
  // 指定哪些文件收集覆盖率,亦或是排除那些文件,一般入口文件App.vue会被排除
  // 或者设置文件、结构非常简单的文件、其他插件文件等,视具体情况适当排除
  collectCoverageFrom: [
    'src/**/*.{js,vue}', // src下所有js/ts/vue文件
    '!src/main.js', // 设置文件排除
    '!src/plugin/*.js',
    '!**/node_modules/**',
    '!src/assets/**',
    '!tests/**/*.js'
  ],
  // 由于某些原因,排除jest测试文件:Layout.spec.js
  testPathIgnorePatterns: [
      'tests/views/Layout.spec.js'
  ],
  coverageDirectory: '<rootDir>/coverage',
  collectCoverage: true,
  coverageReporters: ['lcov', 'text-summary'],
  testURL: 'http://localhost/',
  setupFiles: ['<rootDir>/tests/unit/lib/register-context.js']
}
  • testMatch 这块编写单侧时可以指定到某一确定文件,来具体提高某一文件的单元测试覆盖率。 image.png

  • collectCoverage 和 collectCoverageFrom 的配置可以在本地生成coverage目录,打开coverage/lcov-report/index.html 文件 能看到具体的单测覆盖率,如图

image.png 打开其中文件能看到当前单元覆盖率,以及当前方法是否覆盖,如图所示: image.png 未覆盖的已用红圈标出。实际单测过程中尽量mock不同的条件,进入不同的case当中,能大幅提高单测覆盖率。

  • 具体单测文件写法(包含不同情况)
    • 方法的模拟 (window方法,$message方法, promise方法)
    • 插件的模拟(store,router,子组件)
    • 场景覆盖 (data,computed,watch,methods,components)
    • 提高覆盖率 (不同case,断言方法被访问,覆盖dom操作) ps: 尽量mock不同的条件,进入不同case中断言,能大幅提高覆盖率。如果其中有case结果模拟不到就尽量模拟方法被访问