前端单元测试配置-Mocha和Jest结合Vue&React&Angular

结合现有项目,将使用到的前端框架(Vue、Angular、React)进行单元测试配置,整理配置文档

Vue

vue-cli在创建项目时可选择单元测试框架(Mocha 或 Jest),此处包含两种测试框架配置

Vue & Mocha

项目创建

项目创建时选择 Mocha 的Unit Testing

vue create vue-mocha

# 选择手动配置
? Please pick a preset: 
  zcloud (router, vuex, less, babel, eslint, unit-jest) 
  default (babel, eslint) 
❯ Manually select features 

? Please pick a preset: Manually select features
? Check the features needed for your project: 
 ◉ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
 ◉ Router
 ◉ Vuex
 ◉ CSS Pre-processors
 ◉ Linter / Formatter
 ◉ Unit Testing
❯◉ E2E Testing

# 单元测试 mocha + chai
 ? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex, CSS Pre-processors, Linter, Unit, E2E
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with node-sass)
? Pick a linter / formatter config: Standard
? Pick additional lint features: (Press  to select,  to toggle all,  to invert selection)Lint on save
? Pick a unit testing solution: (Use arrow keys)
❯ Mocha + Chai 
  Jest 

添加测试报告mochawesome

现有架构测试报告都是在命令行展示,现在我们要将结果输出并展示在页面上

首先在项目中安装 mochawesome:

npm install --save-dev mochawesome

然后在 package.json 中修改 test:unit 命令如下:

"test:unit": "vue-cli-service test:unit --reporter=mochawesome"

添加测试覆盖率nyc

首先,在项目中安装所需依赖:

npm i --save-dev babel-plugin-istanbul istanbul-instrumenter-loader nyc

接着在项目根目录下新建 nyc.config.js 文件,其内容如下:

// 探索istanbul/nyc代码覆盖工具的原理 https://zhuanlan.zhihu.com/p/88524418
module.exports = {
  'check-coverage': true,
  'per-file': true,
  'lines': 0,
  'statements': 0,
  'functions': 0,
  'branches': 0,
  'include': [
    'src/**/*.js',
    'src/**/*.vue'
  ],
  'exclude': [
    'src/abandon-ui/**',
    'src/*.js',
    '**/*.spec.js'
  ],
  'reporter': [
    'lcov',
    'text',
    'text-summary'
  ],
  'extension': [
    '.js',
    '.vue'
  ],
  'cache': true,
  'all': true
}

完成后,在项目根目录新建 vue.config.js, 其内容如下:

const path = require('path')
const testMode = process.env.NODE_ENV === 'test'

module.exports = {
  lintOnSave: false,
  productionSourceMap: false,

  chainWebpack: config => {

    if (testMode) {
      config.merge({
        devtool: 'eval'
      })
      config.module
        .rule('istanbul')
        .test(/\.(js|vue)$/)
        .include
        .add(path.resolve(__dirname, '/src'))
        .end()
        .use('istanbul-instrumenter-loader')
        .loader('istanbul-instrumenter-loader')
        .options({ esModules: true })
        .before('babel-loader')
    }
  }
}

完成后,打开项目根目录下的 babel.config.js 文件,修改如下:

const testMode = process.env.NODE_ENV === 'test'

module.exports = {
  presets: ['@vue/cli-plugin-babel/preset']
  presets: ['@vue/cli-plugin-babel/preset'],
  plugins: testMode ? ['babel-plugin-istanbul'] : []
}

最后,打开 package.json 文件,修改 test:unit 命令:

"test:unit": "nyc vue-cli-service test:unit --reporter=mochawesome"

单元测试文件书写位置调整

如果我们的项目是一个去中心化的架构,我们可能希望我们的单元测试文件位于我们的组件旁边,而不是都写在 tests/unit/ 目录下。

在 tests/unit 目录下新建 index.spec.js 文件,其内容如下:

// require all src files that ends with .spec.js
const srcContext = require.context('../../src/', true, /\.spec.js$/)
srcContext.keys().forEach(srcContext)

修改.eslintrc.js 配置

overrides: [
  {
    files: [
      '**/__tests__/*.{j,t}s?(x)',
      '**/tests/unit/**/*.spec.{j,t}s?(x)',
      '**/src/**/*.spec.{j,t}s?(x)'
    ],
    env: {
      mocha: true
    }
  }
]

至此,Vue+Mocha单元测试基本配置完成,执行test:unit 命令后,可在项目中查看测试效果

Vue & jest

项目创建

项目创建时选择 Jest 的Unit Testing,具体操作可查看Mocha的创建

添加测试报告

安装依赖:

npm i --save-dev jest-html-reporter

配置jest.config.js

jest集成了测试所需的功能,包括断言,覆盖率,以及测试报告等,测试配置文件如下:

module.exports = {
  preset: '@vue/cli-plugin-unit-jest',
  moduleFileExtensions: [
    'js',
    // 告诉 Jest 处理 `*.vue` 文件
    'vue'
  ],
  moduleNameMapper: {
    // 支持源代码中相同的 `@` -> `src` 别名
    '^@/(.*)$': '/src/$1'
  },
  transform: {
    // 用 `babel-jest` 处理 `*.js` 文件
    '^.+\\.js$': '/node_modules/babel-jest',
    // 用 `vue-jest` 处理 `*.vue` 文件
    '.*\\.(vue)$': '/node_modules/vue-jest'
  },
  testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)', '**/src/**/*.spec.{j,t}s?(x)'],
  snapshotSerializers: [
    // 快照的序列化工具
    '/node_modules/jest-serializer-vue'
  ],
  displayName: {
    name: 'CLIENT',
    color: 'blue'
  },
  // 成多种格式的测试覆盖率报告  可选
  collectCoverage: true,
  collectCoverageFrom: ['**/*.{js,vue}', '!**/node_modules/**', '!**/dist/**', '!**/coverage/**'],
  // report配置
  reporters: [
    'default',
    [
      './node_modules/jest-html-reporter',
      {
        pageTitle: 'test report',
        outputPath: 'testReport/JesttestReport.html',
        includeFailureMsg: true
      }
    ]
  ]
}

至此,Vue+Jest单元测试基本配置完成,执行test:unit 命令后,可在项目中查看测试效果。

Jest相对Mocha而言,配置简单许多,开箱即用,考虑到不同的库需要学习不同的API,踩坑的风险也随之提升,后续框架均只采用Jest进行配置。

Angular

Angular脚手架在创建项目时自动配置单元测试,采用Karma和Jasmine,引入Jest需要迁移

angular & Jest

配置时默认使用angular脚手架创建的项目

迁移

第一步,下载相关的依赖包:

npm i --save-dev jest jest-preset-angular @types/jest jest-html-reporter

第二步,在pakage.json中对Jest进行配置,也可直接配置jest.config.js

"jest": {
  "preset": "jest-preset-angular",
  "setupFilesAfterEnv": ["/src/setupJest.ts"]
}

第三步,在src目录下创建上一步中设置的 setup 文件setupJest.ts

import 'jest-preset-angular'; // jest 对于 angular 的预配置

接下来,我们就可以在 package.json 的 script 中配置 test 的命令了:

"test": "jest"

此时,在命令行中运行测试命令,就应该能够顺利把测试跑起来并通过了。如果没有通过,可能是因为我们在src/tsconfig.spec.json中的 file 配置中有test.ts的配置,这是 Karma 的 setup 文件,删掉这行配置并删除对应的文件,(src/tsconfig.app.json中出现的test.ts也可一并删除),重新执行npm run test即可

删除 Karma 相关代码

  • 删除相关依赖包(@types/jasmine @types/jasminewd2 jasmine-core jasmine-spec-reporter 因为在 e2e 测试中有使用所以不能删除):
    npm uninstall karma karma-chrome-launcher karma-coverage-istanbul-reporter karma-jasmine karma-jasmine-html-reporter
    
  • 删除文件src/karma.config.js
  • 删除 angular.json中test的配置
  • src/tsconfig.spec.jsoncompilerOptions.type的配置移除 jasmine, 加上 jest。

至此,Jest测试环境就算顺利搭建好了

React

Create React App创建后react项目后,是默认集成Jest的,所以我们只需完善配置即可

浅层渲染

如果你希望测试独立于它们渲染的子组件的组件,我们建议使用 Enzyme 的 shallow() 渲染API。

第一步,安装enzyme依赖

npm install --save-dev enzyme enzyme-adapter-react-16 react-test-renderer

第二步,修改src/setupTests.js

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

// 添加在测试中模拟的浏览器API
const localStorageMock = {
  getItem: jest.fn(),
  setItem: jest.fn(),
  removeItem: jest.fn(),
  clear: jest.fn(),
};
global.localStorage = localStorageMock;

覆盖率报告

Jest 有一个集成的覆盖率报告器,可以很好地与 ES6 配合使用,无需配置。运行 npm test -- --coverage

进阶学习文档

  • Jest文档:官方文档、中文文档
  • Vue单元测试文档:中文文档
  • Angular单元测试文档:官方文档
  • React单元测试文档:中文文档

你可能感兴趣的:(前端单元测试配置-Mocha和Jest结合Vue&React&Angular)