0%

Jest单元测试学习(一)

不同的语言框架都有其对应的单元测试框架,接触过的有java-JUntil、python-Unittest、javascript-Jest等等,这里就Jest的使用做个持续记录。

常见的单元测试,基本都是由开发人员在开发过程用于调试的,特别是涉及大量数据处理方法的后端人员。
前端的单元测试在很多人看来都是一个可有可无的东西,因为测试在验收的时候对页面的功能都会操作一遍,写单元测试相当于做无用功。
就测试角度来看,无论是前端应用还是后台代码,单元测试可在项目整体未转测时就开始局部方法的覆盖测试,既可提高测试人员对UI逻辑的了解深度,也是一道质量保证。且当前前端应用多采用MVC结构开发,也为针对单元方法的测试提供了便利。产品稳定后期,借助Jest的snapshot功能及可靠的测试数据设计,可以高覆盖的进行回归测试。

Jest简介:

Jest是由Facebook发布的开源的、基于Jasmine的JavaScript单元测试框架。Jest源于Facebook两年前的构想,用于快速、可靠地测试Web聊天应用。它吸引了公司内部的兴趣,Facebook的一名软件工程师Jeff Morrison半年前又重拾这个项目,改善它的性能,并将其开源。Jest的目标是减少开始测试一个项目所要花费的时间和认知负荷,因此它提供了大部分你需要的现成工具:快速的命令行接口、Mock工具集以及它的自动模块Mock系统。此外,如果你在寻找隔离工具例如Mock库,大部分其它工具将让你在测试中(甚至经常在你的主代码中)写一些不尽如人意的样板代码,以使其生效。Jest与Jasmine框架的区别是在后者之上增加了一些层。最值得注意的是,运行测试时,Jest会自动模拟依赖。Jest自动为每个依赖的模块生成Mock,并默认提供这些Mock,这样就可以很容易地隔离模块的依赖。

安装:

因为是Facebook官方的工具,所以如果用官方脚手架创建的react及react native工程都是自带jest的。
如果没有我们需要手动安装下:

1
npm install --save-dev jest jest-cli babel-jest

由于我的项目是react native的,于是我再package.json里做了如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
"jest": {
"preset": "react-native",
"globals": {
"__DEV__": true
},
"transform": {
"^.+\\.js$": "babel-jest"
},
"transformIgnorePatterns": [
"node_modules/(?!react-native|react-navigation)/"
]
},
...

其中,babel-jest的作用是让单测代码支持ES6。transformIgnorePatterns的配置用来处理es2015的模块导入时的报错。如下:

1
2
3
4
5
6
7
8
9
D:\react\bangbang\node_modules\static-container\StaticContainer.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import React, { Component, Children } from 'react';
^^^^^^

SyntaxError: Unexpected token import

1 | import React, {Component} from 'react'
2 | import {View, StyleSheet, ActivityIndicator, Dimensions} from 'react-native'
> 3 | import RootSiblings from 'react-native-root-siblings'

同样package.json需要配置个启动脚本:

1
2
3
4
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest",
},

至此,Jest已经安装配置完毕。为了验证安装配置是否成功,按照官方文档里的例子写个脚本验证下:
在任意位置新建一个sum.js,内容如下:

1
2
3
4
function sum(a, b) {
return a + b;
}
module.exports = sum;

同级目录下新建一个测试脚本:sum.test.js(提示:Jest 的测试脚本名形如*.test.js,不论 Jest 是全局运行还是通过npm test运行,它都会执行当前目录下所有的*.test.js 或 *.spec.js 文件、完成测试。)

1
2
3
4
5
const sum = require('./sum');

test('测试1+2的结果是3', () => {
expect(sum(1, 2)).toBe(3);
});

右键sum.test.js运行,可以看到结果:

1
2
3
4
5
6
7
 PASS  app/services/api.test.js
√ 测试1+2的结果是3 (3ms)

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.167s

关于Jest本身的其他很多特性,后面将持续阐述。