前言:本文用于2018/1/30晚内部分享。
主题:前端单元测试
正文:
一、思考
我的目标是,如何浅入本次的主题,让愿意接收陌生信号的“对象”快速简单的get到信号,并且对本次分享产生一个小兴趣。
二、What
本章节主要讲述前端单元测试做什么,vue单元测试做什么。
(1) 基础概念
- 测试的概念:测试是检测你的应用代码(也叫“生产代码”)是否按预期执行的过程。测试可以手动测试,也可用自动测试(用编写好的代码代替人工做检测的工作),本文主要围绕后者展开。
- 测试的分类:测试按照不同标准分类很多,不属于同一次元不能作比较。前端测试根据测试范围分类主要分为单元测试和端到端测试(E2E测试)。
(2) 前端单元测试(Unit Test)
- 前端单元测试:是以单元为单位进行的测试。
- 单元:可以是一个函数、一个模块、一个包或者一个类,甚至是一个对象,在不同编程语言中定义不一样。
- 为什么需要单元测试:使代码健壮,质量高(减少 QA 测试报告的反馈),兼容各种临界点,保证代码的整洁清晰。通俗的说,就是降低返工率,减少QA在开发者已投入其他开发工作时反馈bug从而打断当前的工作进度的现象。
(3) vue单元测试
vue单元测试也是单元测试,它的“单元”泛指vue组件,简单来说就是以vue组件为单位进行的单元测试。
三、HOW
本章节主要从理论层面讲述如何实现vue的单元测试。
(1)测试框架:
vue-cli 自带了测试框架:jest(Javascript单元测试工具)、karma and Mocha、e2e(nightwatch)等。单元测试框架选用karma+mocha+chai。
- Karma:一个测试运行器,用于启动浏览器,运行测试案例并将结果报告给我们。该工具的主要作用是将项目运行在各种主流Web浏览器进行测试。
- Mocha:一个测试框架。可结合chai断言库使用。
- Chai:一个测试断言库,提供了更好的断言语法。所谓断言,就是对组件做一些操作,并预言产生的结果。如果测试结果与断言相同则测试通过。
(2) 运行过程
karma的配置文件中,可以配置files参数,即引入测试脚本,测试运行时会扫描到这些测试脚本,运行其中的测试case,得到测试报告。
四、Use
本章节主要讲述vue单元测试的具体实施,包括测试环境搭建、配置简述、测试脚本编写、测试运行。
(1) 测试环境搭建
创建一个vue项目,init 时 “Set up unit tests”选择yes 、"Pick a test runner"选择Karma即可。vue-cli 会自动生成karma配置文件(karma.conf.js)。
(2) 配置简述
/test/unit/karma.conf.js:
// This is a karma config file. For more details see // http://karma-runner.github.io/0.13/config/configuration-file.html // we are also using it with karma-webpack // https://github.com/webpack/karma-webpack var webpackConfig = require('../../build/webpack.test.conf') // 引入webpack配置 module.exports = function karmaConfig (config) { // 设置karma配置 config.set({ // to run in additional browsers: // 1. install corresponding karma launcher // http://karma-runner.github.io/0.13/config/browsers.html // 2. add it to the `browsers` array below.
// 设置默认打开的浏览器 browsers: ['PhantomJS'],
// 测试框架 frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'],
// 设置测试覆盖率输出插件 reporters: ['spec', 'coverage'],
// 测试文件入口 files: ['./index.js'],
// 预处理器--用webpack解析,同时显示测试文件路径 preprocessors: { './index.js': ['webpack', 'sourcemap'] },
// 引入webpack webpack: webpackConfig,
// 是否打印[webpack]打包信息
webpackMiddleware: { noInfo: true },
//karma-coverage配置,配置测试覆盖率的输出目录及格式
coverageReporter: { dir: './coverage', reporters: [ { type: 'lcov', subdir: '.' }, { type: 'text-summary' } ] } }) }
test/unit/index.js
import Vue from 'vue' Vue.config.productionTip = false // require all test files (files that ends with .spec.js)
// 加载所有的测试脚本 const testsContext = require.context('./spec', true, /.spec$/) testsContext.keys().forEach(testsContext) // require all src files except main.js for coverage. // you can also change this to match only the subset of files that // you want coverage for.
// 加载所有的资源文件,及src目录下的除了main.js文件的所有文件,即要覆盖所有的代码 const srcContext = require.context('../../src', true, /^./(?!main(.js)?$)/) srcContext.keys().forEach(srcContext)
package.json:
应当包含这样的script:
"unit": "jest --config test/unit/jest.conf.js --coverage",
(3) 测试脚本编写与运行
1、 基础知识:
- 测试脚本都要放在
test/unit/specs/
目录下。 - 脚本命名方式为
[组件名].spec.js
。 - 所谓断言,就是对组件做一些操作,并预言产生的结果。如果测试结果与断言相同则测试通过。
- 单元测试默认测试
src
目录下除了main.js
之外的所有文件,可在test/unit/index.js
文件中修改。 - Chai断言库中,
to be been is that which and has have with at of same
这些语言链是没有意义的,只是便于理解而已。 - 测试脚本由多个
descibe
组成,每个describe
由多个it
组成。
2、describe
的钩子(生命周期)
describe('hooks', function() { before(function() { // 在本区块的所有测试用例之前执行 }); after(function() { // 在本区块的所有测试用例之后执行 }); beforeEach(function() { // 在本区块的每个测试用例之前执行 }); afterEach(function() { // 在本区块的每个测试用例之后执行 }); // test cases });
3、简单的测试脚本:
测试对象:/Src/components/HelloWorld.vue
就是vue创建项目时生成的文件,没有做任何改动,以下是抽取出来的主要代码:
<template> <div class="hello"> <h1>{{ msg }}</h1> </div> </template> <script> export default { name: 'HelloWorld', data () { return { msg: 'Welcome to Your Vue.js App' } } } </script>
测试脚本:/test/unit/specs/HelloWorld.spec.js
仍然没有做任何改动,只增加了注释:
import Vue from 'vue' import HelloWorld from '@/components/HelloWorld'
// 一个 describe 代表一个测试套件,可以有多个 it块 describe('HelloWorld.vue', () => {
// 一个it块代表一个 测试case it('should render correct contents', () => {
// 获取组件实例 const Constructor = Vue.extend(HelloWorld)
// 将实例挂载到 DOM 上 const vm = new Constructor().$mount()
// 断言实际结果与预期结果一致 ———— 断言“hello”class内的 “h1” 标签文本内容等于‘Welcome to Your Vue.js App’ expect(vm.$el.querySelector('.hello h1').textContent) .to.equal('Welcome to Your Vue.js App') }) })
运行单元测试:#npm run unit
查看测试报告(覆盖率):报告自动写入该目录 /test/unit/coverage/lcov-report/ ....
在浏览器查看测试报告:
下次将深入组件测试,编写运行更为复杂的测试脚本。
五、Resource
本章节分享本人在学习过程收集的资料,以供感兴趣者继续深入学习。
(1) 官网:
(2) 社区:
(3) openSource:
(4) 其他: