koude0是Facebook创建的流行测试框架,每月下载超过5000万个,导致many problems用于后端开发人员。
在本文中,我试图回顾一下jest
的十字架和喜悦,以及如何处理它以及什么引起它。
开玩笑如何工作?
jest
是一个JavaScript测试框架,其中包含许多功能,包括在其网站上写的isolated
。隔离功能的目标性能:
测试通过在自己的过程中运行以最大化性能而并行。
jest
的隔离来自使用引擎盖下的koude5核心模块的its architecture。
vm
模块让jest
运行每个测试文件,并具有其自己的临时上下文。上下文包括所有global
类,例如Array
,Error
,Date
和许多其他类 - 例如,describe
和it
测试功能。 (Here the jest source code that does the trick)
由于jest
覆盖了其中的一些组件,以为您提供诸如模拟,假时钟和快速测试执行之类的精美功能,因此它必须设置所有vm
的global
数据以设置将执行测试源代码的上下文。 P>
不幸的是,当node.js核心模块创建一个global
类的新实例时,他们将不会使用 vm
的上下文,但它们落后于本地实现。
这意味着instanceof
运营商will not workAs期望的,它将产生假否定性!
您可以在以下test.js
摘要文件中快速获取此问题:
const { parseArgs } = require('util')
test('Array is not an Array', async () => {
const { values } = parseArgs({
args: ['--bar', 'a', '--bar', 'b'],
options: {
bar: {
type: 'string',
multiple: true
}
}
})
expect(values.bar).toEqual(['a', 'b'])
expect(values.bar).toBeInstanceOf(Array) // it will fail
})
通过使用命令jest test.js
_(带有默认的jest
configuration)进行上述测试,_it将在stange错误中失败:
Array is not an Array
expect(received).toBeInstanceOf(expected)
Expected constructor: Array
Received constructor: Array
27 | })
28 | expect(values.bar).toEqual(['a', 'b'])
> 29 | expect(values.bar).toBeInstanceOf(Array)
这似乎是一个小问题,您只需要避免使用instanceof
操作员,但事实并非如此。更大的问题是instanceof
操作员可以由依赖项树使用来执行一些检查,这些条件将失败。
例如,从其代码库中快速化removed the koude19 operator,因为它给那些依赖jest
作为测试框架的开发人员引起了问题。
如何修复它?
这取决于ð
您开箱即用。在the Node.js repository上有一个空旷的问题,可以让node:vm
模块使用vm
的上下文,但仍然开放。似乎Node.js Core团队通过实施新的ShadowRealm规范有兴趣解决此问题,我认为我们将在2023年取得一些进展。
如果您迫不及待,则使用koude29自定义测试环境有一个非常快速的解决方案。
如果安装此模块,并且使用命令运行以前的代码:
jest --testEnvironment jest-environment-node-single-context test.js
现在,所有人都可以按预期工作:
PASS ./test.js
Array is not an Array (5 ms)
请注意,现在测试工作是因为jest
隔离功能通过在同一上下文中运行所有测试而完全禁用。
另一个工作解决方案是使用新的jest
跑步者:koude32。它为每个测试文件旋转一个Node.js Worker线程,从而为您提供了jest
的相同隔离功能,但没有vm
的上下文。请注意,并非所有jest
功能都由该跑步者支持,但是所有最常用的功能都在起作用!
因此,安装它后,您可以通过运行命令来验证测试是绿色的:
jest --runner jest-light-runner test.js
概括
jest
是一个很好的测试框架,它对前端应用程序效果很好,但是如果您的依赖性依赖instanceof
,您可能会遇到一些问题。
我们讨论了如何以不同的方式解决此问题:
- 采用
jest-environment-node-single-context
自定义测试环境及其局限性 - 使用
jest-light-runner
Runner获得jest
的相同隔离功能,但具有一部分功能 - 向您使用的模块的存储库打开一个问题,并要求删除
instanceof
操作员,仍然是一个很好的做法 - 选择另一个测试框架。 我个人更喜欢koude42
jest
架构对于在浏览器中运行并且具有不同的global
上下文的前端应用程序很有意义,但它不适合Node.js应用程序。
我不喜欢在我的测试和生产环境中使用其他global
上下文的概念。
现在跳入此article source code尝试我写的代码段来验证我的发现。
如果您喜欢这篇文章,请在Twitter上发表评论,分享和关注我!