跳至主内容

Jest 20:💖 愉悦的测试体验 & 🏃🏽 多项目运行器

· 7 分钟阅读
非官方测试版翻译

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

几个月前我们发布了 Jest 19,它带来了重大新功能并成为当时最大的版本更新。而今天的 Jest 20 包含的变更量是前版的两倍,彻底重写了测试运行器,并新增了测试 API。新版本为项目提供了前所未有的自定义和配置能力,同时确保升级过程丝滑流畅。超越"无痛 JavaScript 测试",我们相信 Jest 现在提供了愉悦的 JavaScript 测试体验。让我们深入看看最亮眼的新特性和改进:

多项目运行器 & 配置重构

此前,Jest 每次只能处理一个项目。当您同时开发多个具有独立设置的小型项目时,这种限制常令人困扰。Jest 20 彻底重写了测试运行器,使其能在单实例中并行运行多个项目——例如同时处理 React 前端和 Node.js 后端项目。以下视频展示了 Jest 同时为 ReactRelayYarn 和 Jest 自身运行测试的场景:

multi-runner

Jest 现在会在首次测试运行后折叠使用指南,以节省终端纵向空间。

此外,我们全面重构了 Jest 内部的配置系统。现在您可以通过 CLI 传递任意配置选项来覆盖配置文件中的设置。同时,Jest 默认会查找 jest.config.js 文件,这意味着您既可以用 JavaScript 定义配置,也能像以前一样通过 package.json 配置。这些新特性让您能以前所未有的强大方式组合使用 Jest。例如在 monorepo 中,若想根据跨项目提交的变更文件确定 Jest 将运行哪些测试,您现在可以这样组合 CLI 参数:

$ jest --projects projectA projectB --listTests --findRelatedTests projectA/banana.js projectB/kiwi.js
[
"projectA/banana.test.js",
"projectB/kiwi.test.js",
"projectB/pineapple.test.js",
]

这在持续集成(CI)系统中尤其有用——您可能只想为 Pull Request 运行部分测试,避免每次微小变更都要执行数千个测试文件。

最后,我们现在正确映射了 TypeScript 的代码覆盖率,并通过在 worker 进程中处理未测试文件的覆盖率计算,显著加速了这一功能。

新增与优化的测试 API

我们对测试 API 进行了多项增补和改进,帮助开发者编写更高效的测试。特别说明:所有这些改进都完全来自社区贡献者!

  • 更优异步测试:通过 expect 的 resolves/rejects 修饰符新增 async/Promise 支持:expect(Promise(…)).resolves.toEqual(…)查看文档

  • 期待 n 条断言:除现有 expect.assertions(n) 外,新增的 expect.hasAssertions() 可确保测试至少包含一条断言。

  • Lint 插件:在 eslint-plugin-jest 中添加了 valid-expect 规则,确保调用 expect 后必跟断言。这将避免出现类似 expect(banana); 这样缺失断言调用的错误。

  • 美化格式插件:新增了多个美化格式插件。现在能在断言失败和快照中美观地打印 Immutable.js 数据结构和 HtmlElements。

  • 自定义环境:现在可在测试文件的文档块注释中添加 @jest-environment node|jsdom 注解,为单个测试指定不同于默认值的运行环境。

以下示例展示了所有新API如何共同协作,让测试体验更加愉悦:

/**
* @jest-environment node
*/

test('compares apples and bananas', async () => {
expect.hasAssertions(); // Ensure this test has at least one assertion.

await expect(
Promise.resolve(Immutable.Map({apples: 1, bananas: 2})),
).resolves.toEqual(Immutable.Map({apples: 1, bananas: 3}));

expect('banana'); // valid-expect in eslint-plugin-jest will show an error.
});

此示例将输出类似以下的测试失败信息:

testing-apis

破坏性变更

与每个主要版本更新一样,我们进行了多项重大变更,这些变更为未来更大规模的改进铺平道路,并将测试体验推向新高度。本次更新中,我们尽力确保只破坏那些预计不会影响大多数Jest用户使用的API:

  • Jasmine 2.5 分支独立:我们最终决定将Jasmine代码库独立分支,全面掌控Jest测试运行器。这将使我们未来能全面改进单元测试体验,目前我们专注于渐进式重构和缩减API表面。如果您发现测试因缺少Jasmine API而失败,jestexpect对象中应存在等效功能。因此我们移除了多数代码库不常用的Jasmine特性。

  • CI环境的新快照策略:快照必须始终与测试及其关联模块一同提交。我们调整了Jest在持续集成(CI)环境或指定--ci标志时不会自动保存新快照的行为。如需覆盖此行为(通常不推荐),可使用--updateSnapshot标志。

  • Babel-Polyfill处理变更:过去Jest在使用babel-jest时会自动加载babel-polyfill,这导致内存泄漏。在多数Node版本中无需加载babel-polyfill,因此我们移除了自动加载机制,改为默认仅包含regenerator-runtime(该库常用于支持旧版Node.js的async/await)。如需babel-polyfill,可在setup文件中手动引入。

其他改进

  • 文档完善:文档对于分享最佳实践、指导用户编写高效测试从而产出优质软件至关重要。过去几周我们大幅扩展了Jest文档,新增了快照测试FAQ、常见JavaScript库集成指南,并完整记录了上述新特性。

  • 多语言支持:现邀请您协助翻译Jest文档,让全球开发者更轻松地掌握Jest。

  • 自定义报告器:通过reporters配置项,Jest现支持自定义测试报告器。您可自由定制Jest输出格式,并通过生成XML等格式报告与其他工具集成。详见文档

  • 代码库健康度:Jest能实现快速迭代,源于我们对代码库健康度的持续投入。我们是prettier的早期采用者,显著提升了Flow覆盖率,通过分支Jasmine优化了测试运行库,并重构了Jest核心模块以奠定未来基础。

  • 缺陷修复:一如既往,我们修复了大量问题。完整变更日志请参阅Jest代码库

Jest主题演讲

近期Jest核心团队及其他贡献者在技术大会上分享了更多关于Jest的实践经验:

一如既往,本次发布的成功离不开你们——JavaScript 社区的鼎力支持。我们怀着无比感激之情,能够有机会与大家共同改进 JavaScript 测试体验。如果您希望为 Jest 贡献力量,请随时通过 GitHubDiscord 联系我们。