总览
Jest是Facebook的开放JavaScript测试库。 它的口号是“令人愉快JavaScript测试”。 尽管Jest可以用来测试任何JavaScript库,但是当涉及到React和React Native时,它就闪闪发光。
这并不奇怪,因为React和Jest都来自Facebook,Facebook和Facebook都是这两者的主要用户。 在本教程中,我将向您展示Jest的八个不同方面,这些方面使它非常适合测试React应用程序。
1.开玩笑是微风
Jest本身很容易安装。 您可以直接使用npm或yarn将其安装在空白处。 我更喜欢纱线。 查看使纱线成为最佳JavaScript软件包管理器的6件事,以了解原因。 就像这样简单:
yarn add --dev jest
如果您更喜欢npm,请输入:
npm install --save-dev jest
在测试之前,让我们编写一些代码进行测试。 这是palindrome.js:
function isPalindrome(s) {
const count = s.length - 1
if count < 2 {
return true
}
for (i = 0; i < (count + 1) / 2; ++i) {
if (s[i] !== s[count - i])
return false
}
return true
}
module.exports = isPalindrome
这是一个名为palindrome.test.js的文件中的一个开玩笑的测试:
const isPalindrome = require('./palindrome')
test('it detects palindromes', () => {
expect(isPalindrome('palindrome')).toBe(false)
expect(isPalindrome('')).toBe(true)
expect(isPalindrome('a')).toBe(true)
expect(isPalindrome('gg')).toBe(true)
expect(isPalindrome('pop')).toBe(true)
expect(isPalindrome('1212')).toBe(false)
})
要运行测试,请将其添加到package.json中:
"scripts": {
"test": "jest"
}
您现在可以使用yarn test
或npm test
:
> yarn test
yarn run v1.1.0
warning package.json: No license field
$ jest
PASS ./palindrome.test.js
✓ it detects palindromes (6ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.667s
Ran all test suites.
✨ Done in 3.15s.
这很简单。 但是,如果您使用react-create-app创建您的React项目,那么您甚至不必这样做。 jest软件包已捆绑在一起,您可以立即开始编写测试。
2.笑话快如闪电
开玩笑的很快。 非常快。 当您的测试受CPU限制时,可以从测试运行中节省大量时间。 Airbnb从Mocha切换到Jest,在具有32核的重型CI机器上,它们的总测试运行时间从超过12分钟减少到只有4.5分钟。 本地测试过去需要45分钟,而现在下降到14.5分钟。
是什么使Jest这么快? 这是几个因素的组合:
- 并行化:这很明显,其他测试框架也使用它。
- 首先运行最慢的测试:这可确保最大程度地利用所有内核。
- 缓存babel转换:减少CPU密集型babel转换。
3.开玩笑是一站式商店
Jest带有内置的匹配器,间谍和它自己的扩展模拟库。 它以前基于茉莉花,因此继承了茉莉花的所有优点。 但是在最新版本中,Jest脱离了Jasmine,但保持了相同的功能并添加了自己的风格和改进。
与基于Mocha的定制测试解决方案进行比较时,很明显易用性是Jest设计的主要关注点。
4.笑话有真棒
模拟是单元测试中非常重要的一部分。 如果您关心快速测试(谁不关心),这尤其重要。
通过模拟,您可以替换不相关的依赖关系,这些依赖关系可能很慢,甚至可以控制依赖于时序的代码的控制时间。 Jest使您可以完全控制依赖关系和主控时间。
简单的模拟功能
模拟依赖关系是单元测试的长期传统。 如果您的代码正在读取文件,写入文件,调用某些远程服务或正在访问数据库,则该过程可能很慢,并且在测试后进行配置和清理可能很复杂。 并行运行时,甚至可能无法正确控制。
在这些情况下,最好用不执行任何操作但仅记录调用事实的模拟函数代替实际的依赖关系,以便您可以验证工作流程。 通过jest.fn()
模拟函数,您可以提供固定的返回值(用于多个连续的调用),并且它记录了调用次数以及每次调用中的参数。
手动模块模拟
有时您可能需要用其数据而不是几个功能来替换整个模块。 通过Jest,您可以通过将自己的同名模块放在__mocks__
子目录中来实现此目的。
每当您的代码使用目标模块时,它将访问您的模拟而不是实际模块。 您甚至可以通过调用jest.Unmock('moduleName')
选择性地选择某些测试以使用原始模块。
计时器模拟
计时是单元测试的祸根。 如果您想测试一分钟后超时的代码怎么办? 每30秒触发一次的代码? 在月底运行对帐算法的特殊代码?
这些很难测试。 您可以遵循原始代码的时序要求(然后您的测试将非常缓慢),也可以操纵时间,这将更加有用。 通过Jest,您可以控制以下与计时器相关的功能:
- setTimeout()
- setInterval()
- clearTimeout()
- clearInterval()
ES6类假人
Jest完全支持ES6类,并提供了多种模拟它们的方法:
- 自动模拟:可让您监视对构造函数和所有方法的调用,但始终返回未定义。
- 手动模拟:在
__mocks__
子目录中实现自己的模拟。 - 模拟具有高阶函数的类工厂。
- 使用
mockImplementation()
或mockImplementationOnce()
选择性mockImplementationOnce()
。
5. Jest支持TypeScript
TypeScript是一种流行JavaScript类型化超集,可编译为普通JavaScript。 Jest通过ts-jest包支持TypeScript。 它描述自己为TypeScript预处理程序,并具有对Jest的源映射支持,并且社区非常活跃。
6.笑话已经覆盖了你
Jest具有内置的覆盖率报告。 您的测试仅取决于其覆盖范围。 如果仅测试80%的代码,则其余20%的错误将仅在生产中发现。
有时,从业务角度来看,跳过对系统某些部分的测试是有意义的。 例如,您自己的专家工程师经常使用和更改的内部工具可能不需要与生产代码相同级别的严格测试。 但是,无论如何,这应该是一个有意识的决定,并且您应该能够准确地看到系统不同部分的测试覆盖范围。
以下是为简单回文示例生成覆盖率报告的方法:
> yarn test --coverage
yarn run v1.1.0
warning package.json: No license field
$ jest "--coverage"
PASS ./palindrome.test.js
✓ it detects palindromes (4ms)
-------------- |----------|----------|----------|----------|
File | % Stmts | % Branch | % Funcs | % Lines |
-------------- |----------|----------|----------|----------|
All files | 100 | 100 | 100 | 100 |
palindrome.js | 100 | 100 | 100 | 100 |
-------------- |----------|----------|----------|----------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.712s
Ran all test suites.
✨ Done in 3.41s.
7.开玩笑做快照
快照测试很棒。 它使您可以捕获表示您呈现的组件的字符串并将其存储在文件中。 然后,您可以稍后对其进行比较,以确保UI不变。 虽然它是React和React Native应用程序的理想选择,但是您可以使用快照来比较其他框架的序列化值。 如果您实际上更改了UI,那么您当然需要更新快照文件以反映出来。
8. Jest进行手表的Delta测试
Jest可以在监视模式下运行,在该模式下,只要更改代码,它就会自动运行测试。 您使用--watchAll
命令行参数运行它,它将监视您的应用程序的更改。 我在监视模式下开玩笑,故意向palindrome.js引入了一个错误,结果如下:
FAIL ./palindrome.test.js
✕ it detects palindromes (11ms)
● it detects palindromes
expect(received).toBe(expected) // Object.is equality
Expected value to be:
true
Received:
false
6 | expect(isPalindrome('a')).toBe(true)
7 | expect(isPalindrome('gg')).toBe(true)
> 8 | expect(isPalindrome('pop')).toBe(true)
9 | expect(isPalindrome('1212')).toBe(false)
10 | })
11 |
at Object..test (palindrome.test.js:8:30)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 0.598s, estimated 1s
Ran all test suites.
Watch Usage: Press w to show more.
结论
Jest是一个易于设置的快速测试框架。 它由Facebook积极开发和使用,以测试其所有React应用程序以及许多其他开发人员和公司。
它在一个方便的软件包中提供了您所需的全部内容,支持TypeScript,并且IMO是React和React Native应用程序测试的最佳选择。 从其他测试解决方案迁移也非常容易。
请记住,React越来越受欢迎。 实际上,我们在Envato市场中有许多商品可供购买,审查,实施等。 如果您正在寻找有关React的其他资源,请随时检查 。
翻译自: https://code.tutsplus.com/tutorials/8-things-that-make-jest-the-best-react-testing-framework--cms-30534