您应该使用jest作为测试库吗?
#node #测试 #jest

koude0是Facebook创建的流行测试框架,每月下载超过5000万个,导致many problems用于后端开发人员。

在本文中,我试图回顾一下jest的十字架和喜悦,以及如何处理它以及什么引起它。

开玩笑如何工作?

jest是一个JavaScript测试框架,其中包含许多功能,包括在其网站上写的isolated。隔离功能的目标性能:

测试通过在自己的过程中运行以最大化性能而并行。

jest的隔离来自使用引擎盖下的koude5核心模块的its architecture

vm模块让jest运行每个测试文件,并具有其自己的临时上下文。上下文包括所有global类,例如ArrayErrorDate和许多其他类 - 例如,describeit测试功能。 (Here the jest source code that does the trick

由于jest覆盖了其中的一些组件,以为您提供诸如模拟,假时钟和快速测试执行之类的精美功能,因此它必须设置所有vmglobal数据以设置将执行测试源代码的上下文。

不幸的是,当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上发表评论,分享和关注我!