Jest
Jest是Facebook开源的测试框架,几乎是0配置直接进行单元测试,相对其他测试框架,其一大特点就是内置了常用的测试工具,比如自带断言、测试覆盖率等工具。Jest还有很多好处这里就不一一介绍了,详情可以到Jest官网查看https://jestjs.io/。
Jest 安装
这里默认安装了node。 如果没有安装的,可自行到Node官网进行下载安装https://nodejs.org/。安装好Node后是默认自带NPM包管理工具的。我们可以通过 node -v
和 npm -v
来检测node、和npm是否安装成功,如果都成功的显示了版本号,就说明node和npm都安装成功了。下面我们就可以对Jest来进行安装。
Jest的安装十分简单,就一行命令
npm install --save-dev jest
因为只有在开发的时候我们才去运行测试用例,所以我们在安装Jest的时候加上--save-dev
。安装完成后我们就可以进行Jest的学习了。
Jest初体验
我们可以根据Jest官网给的简单的例子,来体验一下Jest。
我们写一个需要被测试的函数,这个函数就是做一个简单的两个数相加的运算然后返回结果。首先我们先创建一个名为 sum.js
的js文件:1
2
3
4function sum(a, b) {
return a + b;
}
module.exports = sum;
我们用module.exports将这个函数导出
然后我们创建一个名为 sum.test.js
的js文件,这个文件里写我们真正的测试代码:
1 | const sum = require('./sum'); |
然后我们修改 package.json
文件,使得我们输入 npm test
的时候就可以运行我们的测试用例:1
2
3
4
5{
"scripts": {
"test": "jest"
}
}
最后我们输入npm run test
来运行我们的测试用例,并可以看到Jest打印的信息:1
2PASS ./sum.test.js
✓ adds 1 + 2 to equal 3 (5ms)
至此我们就成功的用Jest写了第一个测试用例。
我们可以看到这段测试代码的核心就两条语句
- 调用一个test方法,第一个参数是对这个测试用例的描述,第二参数是一个回调函数,里面是具体的测试方法。
expect(resultValue).toBe(actualValue)
这行代码,我们可以看做,当expect方法中的传入的这个值和toBe这个方法中的值完全相等。这条测试用例就算通过(例子中,resultValue是调用sum函数的返回值,actualValue是我们认为函数运行正确应该返回的值)
我们可以简单地试着实现一下这两行代码,这样能更好的理解。
1 | function expect(resultValue) { //函数的返回值 |
我们可以简单的理解为,expect(resultValue).toBe(actualValue)
就是对上述代码的简化。它的实质其实就是比较。expect函数中resultValue和toBe函数中actualValue是否完全相等。之后会介绍Jest中更多的方法。
配置你的Jest
首先 我们输入下面命令,来生成Jest的配置文件。npx jest --init
注意,我们这里使用的是npx,不是npm,npx的意思是运行的时候,会到
node_modules/.bin
路径和环境变量$PATH
里面,检查命令是否存在。 而不是去全局环境查找命令。
输入完命令后会有几个问题让你回答,来创建基本的配置文件。1
2
3
4
5
6
7
8
9
10
11
12
13Would you like to use Jest when running "test" script in "package.json"? › (Y/n)
这个就是帮你配置package.json当,npm test的时候执行Jest。
Choose the test environment that will be used for testing › - Use arrow-keys. Return to submit.
❯ node
jsdom (browser-like)
选择node环境还是浏览器环境
Do you want Jest to add coverage reports? › (y/N)
是否增加测试覆盖率报告
Automatically clear mock calls and instances between every test? › (y/N)
每次运行测试时自动清除所有mock
回答完问题之后,会生成一个 jest.config.js
的配置文件。我们可以在里面进行Jest更多的配置。我们将会在之后专门来讲Jest的配置,以及通过babel支持TypeScript和ES Modules。
Jest –watch 监视模式运行
--watch
监听变化的测试用例,如果想一个文件改变而运行全部测试用例的话需要使用--watchAll
Jest Matchers 常用匹配器
匹配器(Matchers)是Jest中非常重要的一个概念,它可以提供很多种方式来让你去验证你所测试的返回值
Truthiness
toBe
匹配器:相当于 Object.is 或者 ===toEqual
匹配器: 只匹配内容,不匹配引用。toBeNull
匹配器: 内容是否等于NulltoBeUndefined
匹配器: 内容是否等于undefinedtoBeDefined
匹配器: 希望内容是定义过的。toBeTruthy
匹配器: 内容是否为true。toBeFalsy
匹配器: 内容是否为false。not
匹配器: 在其他匹配器之前,相当于取反操作
与数字相关
toBeGreaterThan
匹配器: 输入的数字是否大于toBeGreaterThanOrEqual
匹配器: 输入的数字是否大于等于toBeLessThan
匹配器: 输入的数字是否小于toBeLessThanOrEqual
匹配器: 输入的数字是否小于等于- 对于浮点数判断相等,为了解决浮点数的bug。要用
toBeCloseTo
匹配器。
与String相关
toMatch
匹配器: 结果中是否包含内容,可以是String也可以是正则
与Array相关
toContain
匹配器: 判断元素是否存在数组中。
与异常相关
- 用
toThrow
匹配器来判断在调用一个函数出现异常时,这个函数是否抛出了异常。
Jest测试异步函数
callback
我们先看下面的测试用例
1 | test('testing asynchronous code', () => { |
在上面这个函数中,fetchData是一个异步的方法,去请求数据,当数据返回时调用,callback函数。我们期望这个异步函数的返回值是”success“。但是Jest并不知道这个异步函数什么时候返回。Jest仅仅只是从头执行到尾。这样这个测试用例是无效的。
为了解决这个问题。Jest提供了一个 done
参数,这个参数通过test函数的回调方法传进去,done
是一个不接受任何参数的方法。具体怎么用我们来看代码
1 | test('testing asynchronous code with done', done => { |
我们对比两个代码可以看出,下面这块代买仅仅是在回调函数中多执行了一句done()
它的意思就是告诉Jest,只有运行到了done()
这个命令的时候,这个test才算完事。如果一直不调用done()
的话会报出超时错误。
但是这里还有点问题。就是当测试不通过的时候,会到的done不被调用。这时我们还需要改写一下代码,用try/catch 来捕获expect错误从而实现我们这个需求。
1 | test('testing asynchronous code with done', done => { |
Promises
如果使用Promise,会简单很多。我们只需要把 promise返回, Jest会等待promise resolve。 如果 rejected 的话,这条测试用例会自动不通过。代码如下。
1 | test('testing asynchronous code', () => { |
如果你用catch捕获了rejected。 那就一定要添加assertions匹配器,assertions匹配器接收一个参数,这个参数表示expect的次数,如果没有出现指定的次数,就会报错。我们改写一下上面的方法。
1 | test('the fetch fails with an error', () => { |
resolves / rejects 匹配器
我们也可以用 resolves和rejects匹配器。我们直接看代码
1 | test('testing asynchronous code', () => { |
Async/Await
最后我们可以用,Await来等待异步函数执行完成,我们只需要把test中的回调函数改写成async/await形式即可。
1 | test('the data is peanut butter', async () => { |
至此我们简单的介绍了Jest的基本用法。更多的用法我们会在下节讲到。