单元测试(Jest 和 Mocha)
Vue CLI 拥有通过 Jest 或 Mocha 进行单元测试的内置选项。
Jest 是功能最全的测试运行器。它所需的配置是最少的,默认安装了 JSDOM,内置断言且命令行的用户体验非常好。不过你需要一个能够将单文件组件导入到测试中的预处理器。我们已经创建了 vue-jest 预处理器来处理最常见的单文件组件特性,但仍不是 vue-loader 100% 的功能。
mocha-webpack 是一个 webpack + Mocha 的包裹器,同时包含了更顺畅的接口和侦听模式。这些设置可以帮助我们通过 webpack + vue-loader 得到完整的单文件组件支持,但这本身是需要很多配置的。
测试运行器就是运行测试的程序。
用 Jest 测试单文件组件
Vue 的单文件组件在它们运行于 Node 或浏览器之前是需要预编译的。我们推荐两种方式完成编译:
1. 通过一个 Jest 预编译器
2. 直接使用 webpack
vue-jest 预处理器支持基本的单文件组件功能,但是目前还不能处理样式块和自定义块,这些都只在 vue-loader 中支 持。如果你依赖这些功能或其它 webpack 特有的配置项,那么你需要基于 webpack + vue-loader 进行设置。
1. 安装 Jest
首先安装 Jest 和 Vue Test Utils:
$ npm install --save-dev jest @vue/test-utils
然后在 package.json 中定义一个单元测试的脚本。
// package.json
{
"scripts": {
"test": "jest"
}
}
2. 在 Jest 中处理单文件组件
安装和配置 vue-jest 预处理器(告诉 Jest 如何处理 *.vue 文件):
npm install --save-dev vue-jest
接下来在 package.json 中创建一个 jest 块:
{
// ...
"jest": {
"moduleFileExtensions": [
"js",
"json",
// 告诉 Jest 处理 `*.vue` 文件
"vue"
],
"transform": {
// 用 `vue-jest` 处理 `*.vue` 文件
".*\\.(vue)$": "vue-jest"
}
}
}
注意:vue-jest 目前并不支持 vue-loader 所有的功能,比如自定义块和样式加载。还有,诸如代码分隔等webpack 特有的功能也是不支持的。如果要使用这些不支持的特性,需要用 Mocha + webpack 来进行测试。
3. 处理-webpack-别名
如果你在 webpack 中配置了别名解析,比如把 @ 设置为 /src 的别名,那么你也需要用 moduleNameMapper 选项为 Jest 增加一个匹配配置:
{
// ...
"jest": {
// ...
// 支持源代码中相同的 `@` -> `src` 别名
"moduleNameMapper": {
"^@/(.*)$": "<rootDir>/src/$1"
}
}
}
4. 为 Jest 配置 Babel
安装 babel-jest(在测试中使用ES6特性):
npm install --save-dev babel-jest
接下来,在 package.json 的 jest.transform 里添加一个入口,来告诉 Jest 用 babel-jest处理 JavaScript 测试文件:
{
// ...
"jest": {
// ...
"transform": {
// ...
// 用 `babel-jest` 处理 js
"^.+\\.js$": "<rootDir>/node_modules/babel-jest"
}
// ...
}
}
注意:默认情况下,babel-jest 会在其安装完毕后自动进行配置。但也需要再次配置 babel-jest。
开启babel-preset-env,同时告诉 babel-preset-env 面向我们使用的 Node 版本。
为了仅在测试时应用这些选项,把它们放到一个独立的 env.test 配置项中 。
.babelrc 文件示例:
{
"presets": [["env", { "modules": false }]],
"env": {
"test": {
"presets": [["env", { "targets": { "node": "current" } }]]
}
}
}
5. 放置测试文件
Jest 推荐在被测试代码的所在目录下创建一个 tests 目录,也可以为测试文件随意设计自己习惯的文件结构。
6. 测试覆盖率
Jest 可以被用来生成多种格式的测试覆盖率报告。
扩展你的 jest 配置 (通常在 package.json 或 jest.config.js 中) 的 collectCoverage 选项,然后添加 collectCoverageFrom 数组来定义需要收集测试覆盖率信息的文件。
{
"jest": {
// ...
"collectCoverage": true,
"collectCoverageFrom": ["**/*.{js,vue}", "!**/node_modules/**"]
}
}
这样就会开启默认格式的测试覆盖率报告。可以通过 coverageReporters 选项来定制它们。
{
"jest": {
// ...
"coverageReporters": ["html", "text-summary"]
}
}
7. 测试规范示例
import { mount } from '@vue/test-utils'
import Component from './component'
describe('Component', () => {
test('is a Vue instance', () => {
const wrapper = mount(Component)
expect(wrapper.isVueInstance()).toBeTruthy()
})
})
用 Mocha 和 webpack 测试单文件组件
通过 webpack 编译所有的测试文件然后在测试运行器中运行。好处是支持 webpack 和 vue-loader 所有的功能。
1. 设置 mocha-webpack
首先要做的是安装测试依赖:
npm install --save-dev @vue/test-utils mocha mocha-webpack
接下来我们需要在 package.json
中定义一个测试脚本。
// package.json
{
"scripts": {
"test": "mocha-webpack --webpack-config webpack.config.js --require test/setup.js test/**/*.spec.js"
}
}
--webpack-config 标识指定了该测试使用的 webpack 配置文件。
--require 标识确保了文件 test/setup.js 会在任何测试之前运行,在该文件中设置测试所需的全局环境。
最后一个参数是该测试包所涵盖的所有测试文件的聚合。
2. 提取 webpack 配置
暴露 NPM 依赖
通过 webpack-node-externals 外置所有的 NPM 依赖:
// webpack.config.js
const nodeExternals = require('webpack-node-externals')
module.exports = {
// ...
externals: [nodeExternals()]
}
源码表
源码表在 mocha-webpack 中需要通过内联的方式获取。推荐配置为:
module.exports = {
// ...
devtool: 'inline-cheap-module-source-map'
}
IDE 中调试需要添加的配置:
module.exports = {
// ...
output: {
// ...
// 在源码表中使用绝对路径 (对于在 IDE 中调试时很重要)
devtoolModuleFilenameTemplate: '[absolute-resource-path]',
devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]'
}
}
3.设置浏览器环境
Vue Test Utils 需要在浏览器环境中运行。可以在 Node 中使用 jsdom-global 进行模拟:
npm install --save-dev jsdom jsdom-global
然后在 test/setup.js 中写入:
require('jsdom-global')()
这行代码会在 Node 中添加一个浏览器环境,这样 Vue Test Utils 就可以正确运行了。
4. 选用一个断言库
Chai 是一个流行的断言库,经常和 Mocha 配合使用。
使用 expect 且令其全局可用,这样我们就不需要在每个测试文件里导入它了:
npm install --save-dev expect
然后在 test/setup.js 中编写:
require('jsdom-global')()
global.expect = require('expect')
测试规范示例
import { shallowMount } from '@vue/test-utils'
import Counter from '../src/Counter.vue'
describe('Counter.vue', () => {
it('increments count when button is clicked', () => {
const wrapper = shallowMount(Counter)
wrapper.find('button').trigger('click')
expect(wrapper.find('div').text()).toMatch('1')
})
})
Mock / Stub
在做单元测试的时候,要测试的方法需要引用很多外部依赖的对象,比如:(发送邮件,网络通讯,记录Log, 文件系统之类的)。 而我们没法控制这些外部依赖的对象。为了解决这个问题,需要用到 Stub 和 Mock 来模拟这些外部依赖的对象,从而控制它们。
Stubs : 通常用于在测试中提供封装好的响应,譬如有时候编程设定的并不会对所有的调用都进行响应。Stubs也会记录下调用的记录,它可以用来记录所有发送的信息或者它发送的信息的数目。(真实对象)
Mocks : 针对设定好的调用方法与需要响应的参数封装出合适的对象。(模拟对象)
stub 使用的状态验证而 mock 使用的是行为验证。如果要基于stub编写状态验证的方法,需要写一些额外的代码来进行验证。而Mock对象用的是行为验证,并不需要写太多的额外代码。
最新文章
- winXP下安装opensshd服务
- 百度地图js根据经纬度定位和拖动定位点
- C++中构造函数调用构造函数
- robotframework笔记1
- Java高级开发工程师
- orientationchange不管用啊
- BZOJ2429: [HAOI2006]聪明的猴子
- jquery获取form表单内容以及绑定数据到form表单
- poj 3308 Paratroopers
- android手机端保存xml数据
- 自定义Data Service Providers
- java中关于转义字符的一个bug
- Windows上Python2与Python3共存
- android弹力效果菜单、组件化项目、电影票选座控件的源码
- nodejs爬虫初试---superagent和cheerio
- Spark:导入数据到oracle
- [NOI 2010]能量采集
- hive防止数据被误删除
- 你可以这么理解五种I/O模型
- 2017年7月25日多校一Function