跳至主内容

Jest 22:优化与自定义运行器

· 8 分钟阅读
Simen Bekkhus
Simen Bekkhus
非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

今天我们正式发布 Jest 的全新主要版本,该版本优化了几乎所有的组件,旨在提供更稳固的测试基础。我们与 Jest 社区共同实施了多项全面改进,帮助您更充分地发挥 Jest 的潜力。同时,我们将自定义运行器功能从实验阶段正式推出,并新增了 jest-worker 包来实现跨进程的并行任务处理。下方列出了主要亮点,但请务必查阅(一如既往)完整的更新日志

告别 Node 4,迎接 JSDOM 11

此版本将停止对 Node 4 的支持,主要原因是我们的核心依赖项 JSDOM 已终止对其的维护。Jest 现在内置了 JSDOM 11,该版本增强了对 SVG 的支持,原生集成了 requestAnimationFrameURLURLSearchParams 等功能,并包含更多改进

自定义运行器 + 通过 jest-worker 实现轻松并行化

在 Jest 21 中我们引入了自定义运行器的概念。此后,Jest 核心贡献者 Rogelio 开发了多个实用运行器:如果您有大量基于其他框架编写的测试用例,但希望立即享受 Jest 的功能特性,请查看 jest-runner-mocha;若您需要为大型代码库执行 linting 操作,通过 Jest 运行 eslint 能带来显著的性能提升

为更精细地控制密集型任务的并行处理(例如文件转换或文件系统遍历),我们专门设计了全新类库。我们开发了名为 jest-worker 的现代化模块,它采用基于 Promise 的架构和易用的 API,允许您将高负载函数委托给子进程执行。与所有 Jest 组件相同,jest-worker 也是 Jest 平台的一部分,即使您从未使用 Jest 本身,也可以自由使用该模块。更多细节请参阅文档

要深入理解自定义运行器及 Jest 作为平台的定位,请观看 Rogelio 在 Reactive Conf 2017 的演讲:Jest 作为平台

测试失败时的代码框展示

为更轻松地定位导致测试失败的断言,我们新增了代码框功能来显示断言所在的上下文环境,使您能专注于自身代码。参考以下测试示例:

test('some test', () => {
function someFunctionWhichShouldThrow() {
if (false) {
throw new Error();
}

return 'success!';
}

expect(someFunctionWhichShouldThrow).toThrow();
});

在 Jest 21 中会显示如下错误:

Jest 21 的失败提示

在 Jest 22 中,我们添加了代码框来为失败断言提供更多上下文信息,同时清理了堆栈跟踪以减少冗余信息:

Jest 22 的失败提示

异步代码错误测试更便捷

您现在可以对 Promise 拒绝使用 toThrowtoThrowErrorMatchingSnapshot 方法,用法与处理同步错误完全一致。

async function throwingFunction() {
throw new Error('This failed');
}

test('asynchronous rejection', async () => {
await expect(throwingFunction()).rejects.toThrowErrorMatchingSnapshot();
});

异步测试环境

当 Google Chrome 团队在 8 月发布 Puppeteer(一种通过编程方式与真实 Chromium 浏览器交互的工具)时,许多开发者希望使用 Jest 编写在 Chrome 中运行的测试。社区通过实现异步测试环境帮助我们实现了这一目标。我们仍在努力优化使用体验,但从今天起,您可以参考本指南了解如何在 Jest 中使用 Puppeteer。

实验性内存泄漏检测

我们为 Jest 新增了实验性的 --detectLeaks 设置,该功能会在测试执行后检测到内部环境实例泄漏时发出警告。当测试套件在测试结束后尝试加载文件时也会触发警报,这意味着您可能忘记等待异步操作完成或未正确清理资源。请注意,该功能仅能检测测试代码中的泄漏(可参考 jest-leak-detector),无法发现应用代码中的内存问题。如果您要报告 Jest 内存使用的 bug,请提供能通过 --detectLeaks 复现失败的测试用例。我们已开始构建更完善的沙盒机制,但目前尚未默认启用。如果您愿意协助开发,欢迎在 Discord 上联系我们!

监听模式优化

在监听模式下,现在可以聚焦于先前失败的测试。此模式下 Jest 不会重新运行已通过的测试,帮助您专注修复失败的测试用例。此外,我们为监听模式添加了插件系统,通过在配置中添加 watchPlugins 模块即可扩展监听模式功能。

Babel 7 支持

Jest 内部使用 Babel 实现代码覆盖率统计和高级模拟功能。Jest 22 现已支持即将发布的 Babel 7。您可以在文档此处查看更多信息。

模拟函数改进

Jest 22 对模拟函数进行了多项优化:首先新增了 mockName 属性支持命名模拟函数,便于在断言失败时定位问题;其次实现了模拟函数在 pretty-format 中的序列化能力,这意味着您现在可以对模拟函数进行快照测试。在 Jest 21 中,expect(jest.fn()).toMatchSnapshot() 会序列化为 [Function],而在 Jest 22 中您将获得如下结构:

test('my mocking test', () => {
const mock = jest.fn().mockName('myMock');

mock('hello', {foo: 'bar'});

expect(mock).toMatchSnapshot();
});

// Serializes to:

exports[`my mocking test 1`] = `
[MockFunction myMock] {
"calls": Array [
Array [
"hello",
Object {
"foo": "bar",
},
],
],
}
`;

Jest 21 的主要亮点

Jest 21 亮点回顾

  1. 在浏览器中使用 expect 和 jest-mock: Michael Jackson 将他优秀的 expect 包捐赠给了 Jest 项目。作为该过渡的一部分,Jest 核心团队在 Kenneth Skovhus 的大力帮助下,使得 jest-matchers(已重命名为 expect)和 jest-mock 都能在浏览器中运行。这意味着虽然你还不能在浏览器中使用 Jest 本身(目前还不行),但你可以使用其出色的断言和模拟功能,例如作为在 Mocha 测试中运行的 Chai 和 Sinon 的替代品。如果你正在从早期的 expect 迁移到新的由 Jest 驱动的 expect,你可以使用 jest-codemods 来自动化迁移。

  2. MIT 许可证:我们将 Jest 的许可证更改为 MIT。欢呼!

  3. 异步错误导致测试套件失败: Jest 曾存在一个缺陷,当异步代码的特定部分抛出错误时会导致其崩溃。该问题已由社区贡献者修复。

  4. 更快的启动速度: 在 Jest 21 中,我们优化了 Jest 的启动过程,使其速度提升了 50% 以上。在运行小型快速测试时,Jest 的巨大开销一直是个问题,而现在这不应再成为阻碍您使用 Jest 的理由。

Jest 社区

围绕 Jest 的社区正在努力让测试体验更加出色。这些是独立于 Jest 主项目的单独项目,但我们想在此重点介绍一些我们个人偏爱的项目。

  • jest-image-snapshot - 由 American Express 开发者开发的自定义匹配器,用于将图像与快照进行比较

  • ts-jest - @kulshekhar 提供的全套工具,助您在 TypeScript 项目中成功运行 Jest

  • jest-codemods - 轻松将测试从其他框架迁移到 Jest

  • jest-plugins - 新的社区项目,专注于简化特定工具(如 React)的测试环境设置,或提供便捷的实用工具

我们还要宣布,最近我们为高质量的 Jest 生态项目创建了新家园——jest-community。这个新的 GitHub 组织已收录我们喜爱的项目,例如 vscode-jestjest-extended 等,这些项目由 Jest 维护者和协作者精心筛选。我们甚至已将 eslint-plugin-jest 迁移至此,并已看到许多优秀贡献,它们正以更快速度独立发布。

Jest Community

将社区项目集中在一个组织下,也是我们试验自动化发布等流程的好方法,这些经验未来也将应用于 Jest 本身。这还使我们能够在项目间共享通用元素,例如 README 的标准化模板(感谢 webpack 社区的启发),让我们所有人更易学习和使用。

如果您有精彩的项目想要分享,请随时联系我们!我们很乐意在此展示您的项目。