尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Jest 30 升级指南:从 v29 迁移的配置、Matcher 与运行时变更全解析

Jest 30 升级指南:从 v29 迁移的配置、Matcher 与运行时变更全解析 Jest 30 升级指南从 v29 迁移的配置、Matcher 与运行时变更全解析【免费下载链接】jestDelightful JavaScript Testing.项目地址: https://gitcode.com/gh_mirrors/je/jest本篇指南面向正在将 Jest 从 v29 升级到 v30 的开发者系统梳理本次大版本升级中所有破坏性变更从 Node/TypeScript 兼容性要求、Expect与 Matcher 别名移除、CLI 与配置项重命名到未处理 Promise 拒绝的判定修正、快照序列化格式调整与内部模块打包重组。阅读完成后你将获得一份可直接对照执行的升级检查清单并能理解这些变更背后的源码级实现原理。升级前的兼容性检查Jest 30 对运行环境提出了更高的要求升级前请先确认你的基础设施满足以下条件Node.jsJest 30 移除了对 Node 14、16、19 和 21 的支持最低支持的版本提升到18.x。请确保 CI 与本地开发环境都运行在受支持的 Node 版本上。TypeScript最低要求提升到5.4。如果你使用了 Jest 的类型定义或任何相关包的类型需要同步升级 TypeScript。jsdomjest-environment-jsdom包现在基于JSDOM v26。DOM 环境的行为可能发生变化如果遇到 DOM 行为差异或新的警告需要对照 JSDOM v21v26 的版本说明逐项排查。这些兼容性要求的完整变更列表可以查看仓库根目录的 CHANGELOG.md30.0.0小节。如果你的项目还在更早的版本可以先参考 docs/UpgradingToJest29.md 完成 v28 → v29 的迁移。Jest Expect 与 Matchers 变更别名 Matcher 函数全部移除所有别名aliasmatcher 名称在 Jest 30 中被彻底移除只保留官方主名称。这些别名从 Jest 26 起就已标记废弃本次升级是最终清理。如果你仍在使用旧名称需要更新测试代码已移除的别名Jest ≤ 29替代的主名称Jest 30expect(fn).toBeCalled()expect(fn).toHaveBeenCalled()expect(fn).toBeCalledTimes(n)expect(fn).toHaveBeenCalledTimes(n)expect(fn).toBeCalledWith(arg)expect(fn).toHaveBeenCalledWith(arg)expect(fn).lastCalledWith(arg)expect(fn).toHaveBeenLastCalledWith(arg)expect(fn).nthCalledWith(n, arg)expect(fn).toHaveBeenNthCalledWith(n, arg)expect(fn).toReturn()expect(fn).toHaveReturned()expect(fn).toReturnTimes(n)expect(fn).toHaveReturnedTimes(n)expect(fn).toReturnWith(val)expect(fn).toHaveReturnedWith(val)expect(fn).lastReturnedWith(val)expect(fn).toHaveLastReturnedWith(val)expect(fn).nthReturnedWith(n, val)expect(fn).toHaveNthReturnedWith(n, val)expect(func).toThrowError(message)expect(func).toThrow(message)两者功能完全一致仅方法名不同可以在代码库中做一次全局搜索替换。如果你使用 ESLint 并配置了eslint-plugin-jest其no-alias-methods规则可以自动完成这类替换。对象匹配默认排除不可枚举属性Jest 30 的jest/expect-utils默认在对象匹配中排除**不可枚举non-enumerable**属性。这会影响expect.objectContaining以及对象相等性比较如toEqual。从源码层面看该行为对应 CHANGELOG 中[jest/expect-utils]的破坏性变更条目CHANGELOG.md。如果此前你的测试依赖了对象上的不可枚举属性参与匹配升级后这类断言可能不再通过需要显式检查这些属性或调整断言方式。CalledWith系列断言的类型推断改进TypeScript 用户需要注意toHaveBeenCalledWith等CalledWith系列 matcher 的类型已改进为推断函数参数类型。这是一次编译期破坏性变更。例如一个被类型标注为接收number参数的函数如果你写了expect(fn).toHaveBeenCalledWith(string)Jest 30 的类型定义配合 TypeScript 5会在编译时直接报错。运行时行为不变——matcher 依然执行相同的比较逻辑但类型系统能更早地暴露参数不匹配问题。修复方式确保测试断言中的实参与函数声明的参数类型一致如果你确实有意以不同类型调用可以使用类型断言。该变更对应 CHANGELOG 中[expect, jest/expect]的CalledWith参数类型推断条目CHANGELOG.md。配置项更新默认支持.mts与.cts文件扩展名Jest 30 扩展了对 ESM 与 TypeScript 模块文件扩展名的默认支持默认的moduleFileExtensions新增.mts和.ctsTypeScript 的 ESM 与 CommonJS 模块默认的testMatch与testRegex模式已更新能够识别.mjs、.cjs、.mts、.cts文件作为测试文件。这些默认值可以直接在源码中验证。在 packages/jest-config/src/Defaults.ts 中moduleFileExtensions的默认值完整列出为moduleFileExtensions: [ js, mjs, cjs, jsx, ts, mts, cts, tsx, json, node, ],而testMatch的默认模式packages/jest-config/src/Defaults.ts为testMatch: [ **/__tests__/**/*.?([mc])[jt]s?(x), **/?(*.)(spec|test).?([mc])[jt]s?(x), ],其中的?([mc])[jt]s?(x)片段正是对.js/.mjs/.cjs/.ts/.mts/.cts/.jsx/.tsx等组合的覆盖。如果项目中存在不希望被当作模块或测试的这类扩展名文件需要调整配置排除反之如果你的测试文件用了这些扩展名Jest 现在默认就能检测到可以删掉之前为此添加的自定义配置。--testPathPattern更名为--testPathPatterns按路径过滤测试的 CLI 参数发生了变化--testPathPattern已更名为--testPathPatterns并且支持传入多个模式用空格分隔或重复使用该参数# 旧写法Jest 29 jest --testPathPatternunit/.* # 新写法Jest 30 jest --testPathPatterns unit/.* integration/.*内部实现上Jest 会把这些模式合并成一个TestPathPatterns对象。如果你以编程方式调用 Jest 的 watch 模式并传入testPathPattern现在必须改为构造TestPathPatterns实例——该类型从jest/pattern包导出仓库中的导出入口见 packages/jest-pattern/src/index.ts。对应的破坏性变更记录在 CHANGELOG.md。--init命令移除交互式初始化配置的命令jest --init已被移除。需要创建 Jest 配置文件时请使用包管理器自带的初始化工具# npm npm init jestlatest # Yarn yarn create jest # pnpm pnpm create jest其他 CLI 变更必需参数校验Jest 现在会校验需要参数的 CLI 标志。例如使用--maxWorkers或--selectProjects时必须提供值如--maxWorkers50%。旧版本中某些标志缺省值时会回退到默认行为现在会直接抛出错误。请检查 npm scripts 或 CI 命令中传入的 Jest 标志是否都带上了参数。该行为对应 CHANGELOG 中[jest-cli]的破坏性变更条目CHANGELOG.md。--filter接口变更自定义测试过滤函数的返回值格式已统一。过滤函数现在必须返回{filtered: Arraystring}形状的对象与文档定义一致。旧版本中可能被接受的直接返回数组等格式不再兼容需要更新所有自定义 filter 实现。测试运行器行为变更未处理 Promise 拒绝Unhandled Rejection判定修正Jest 30 修复了一个误报问题被异步处理在测试 tick 之后才被catch的 Promise 拒绝在 Jest 29 中可能导致测试错误地失败。Jest 30 现在会多等待一个事件循环轮次确认拒绝确实未被处理后才判定测试失败。该修复的源码实现位于 packages/jest-circus/src/unhandledRejectionHandler.ts。其中untilNextEventLoopTurn通过setTimeout(resolve, 0)让出当前事件循环轮次并在hook_success/hook_failure、test_fn_success/test_fn_failure、run_finish等事件点按需等待后再收集unhandledRejectionErrorByPromise等状态中的错误packages/jest-circus/src/unhandledRejectionHandler.ts。这一修复会带来轻微的性能开销尤其是对有意 reject Promise 的测试。为此 Jest 引入了新的配置项waitForUnhandledRejections关闭该选项可以恢复旧行为不额外等待。在仓库的默认配置中该选项的默认值为false见 packages/jest-config/src/Defaults.ts用于在正确性优先与性能优先之间提供取舍对应 CHANGELOG 中的相关条目 CHANGELOG.md。大多数用户不需要改动它但如果你的测试套件出现与未处理拒绝相关的行为变化或性能回退可以通过它显式控制。自定义测试排序器Custom Test SequencerAPI 扩展如果你实现了自定义测试排序器继承 JestTestSequencer的类需要为 Jest 30 更新它现在 Jest 会向排序器额外传递globalConfig和contexts上下文。对应变更见 CHANGELOG.md[jest/core, jest/test-sequencer]的破坏性条目。升级后排序器的相关方法签名应基于这两个新参数编写。Runtime构造必须传入globalConfig对于使用 Jest 编程式 API 的开发者构造Runtime现在必须传入globalConfig参数。如果你调用jest.runCLI或类似的辅助函数需要按更新后的 API 传入全部必需选项。常规的jestCLI 或npm test用法不受影响。该变更记录在 CHANGELOG.md[jest-runtime]的破坏性条目。快照与输出变更升级后部分既有快照需要重新生成原因来自以下几处序列化行为调整移除废弃的 goo.gl 短链接快照测试中废弃的 goo.gl URL 被移除现更新为完整、未缩短的 URL。此变更会改写既有快照内容。快照中包含 Error 的cause属性Jest 30 的快照序列化器在打印Error时会将其cause属性如果存在一并输出。对应实现变更见 CHANGELOG.md[jest-snapshot]对 Error causes 的支持。React 空字符串子节点不再渲染React 专属快照序列化器不再输出空字符串子元素。Jest 29 中 React 元素的空字符串子节点可能在快照中显示为Jest 30 将直接省略视为无内容。对应条目见 CHANGELOG.md[pretty-format]React 插件的破坏性变更。pretty-format改进对象打印ArrayBuffer和DataView现在以人类可读的方式打印而不再是一堆内部字段。对应条目见 CHANGELOG.md。遇到因格式化变化而失败的快照测试可以用jest -uupdateSnapshot重新生成但请先人工确认新输出符合预期避免掩盖真实的断言问题。Jest Mock API 变更jest.genMockFromModule移除遗留函数jest.genMockFromModule(moduleName)已被移除此前已废弃建议改用jest.createMockFromModule。两者行为相同直接替换即可// 旧代码Jest 29 const mockFs jest.genMockFromModule(fs); // 新代码Jest 30 const mockFs jest.createMockFromModule(fs);该移除对应 CHANGELOG.md[jest/environment]的破坏性条目。移除的 Mock 函数相关类型以下与 mock 函数相关的 TypeScript 类型已从公开 API 中移除仅当你在代码中显式导入 Jest API 时受影响例如import {expect, jest, test} from jest/globals;MockFunctionMetadataMockFunctionMetadataTypeSpyInstance如果你曾使用jest.SpyInstance例如为jest.spyOn的返回值标注类型请改用jest.Spied类型详见 docs/MockFunctionAPI.md。jest.mock仅支持大小写敏感的模块路径从 Jest 30 开始jest.mock()只接受大小写完全正确的模块路径// 旧代码Jest 29即使磁盘上只有 filename.js以下写法也能工作 jest.mock(./path/to/FILENAME.js); // 新代码Jest 30仅当磁盘上确实存在 filename.js 时才有效 jest.mock(./path/to/filename.js);这属于边缘情况大多数用户遵循操作系统文件名的大小写习惯不会受影响。建议始终使用正确拼写的模块路径避免后续出现难以排查的破坏。模块与运行时变更ESM 支持与内部打包重组Jest 30 对包的分发结构做了重大调整内部模块统一打包为单文件所有内部模块被合并为单个文件以加快启动速度——安装 Jest 后需要加载的文件数量大幅减少提升性能。副作用是任何对 Jest 包非公开内部路径的深度导入都会失效。例如require(jest-runner/build/testWorker)这类路径并非公开 API将不再存在。解决办法只使用 Jest 的公开 API 和文档化接口如果你认为某个内部模块应当成为公开 API可以向上游提交 Pull Request 将其暴露。该打包改动对应 CHANGELOG.md 的性能条目。提供 ESM 包装wrapper所有官方 Jest 包通过package.json的exports字段正确导出这是让 Jest 能在 ESM 上下文运行的持续工作的一部分。对大多数用户没有直接影响但如果你维护的工具或插件导入了 Jest 模块请确保使用包名导入经由 Node 的模块解析。这些变更对翻内部实现的开发者是破坏性的但对常规 CLI 与配置用法没有影响。升级后正常运行测试即可如果出现与 Jest 自身模块解析相关的错误多半是代码中存在不受支持的导入需要删除或替换。Glob 模式匹配引擎升级Jest 用于文件模式匹配的依赖glob已升级到v10。glob10在花括号展开brace expansion与 extglob 的处理上有细微差异且对某些模式更严格。如果你有自定义的testMatch模式、moduleNameMapper模式或其他基于 glob 的配置多数情况下仍可正常工作但如果某个模式不再匹配到预期文件可能需要针对新 glob 引擎调整写法。升级执行清单完成 Jest 30 升级请按以下顺序操作环境达标确认 Node.js ≥ 18.x、TypeScript ≥ 5.4jsdom 行为变更已评估jest-environment-jsdom现在基于 JSDOM v26。更新配置与 CLI 用法处理被重命名/移除的选项——--testPathPatterns替代--testPathPattern、移除--init改用npm init jestlatest/yarn create jest/pnpm create jest、--maxWorkers等标志补齐参数、--filter返回{filtered: [...]}形状。利用默认新增的.mts/.cts支持删除为覆盖这些扩展名添加的自定义testMatch/moduleFileExtensions配置。替换废弃 API将toBeCalled*/toReturn*/toThrowError等别名 matcher 全部替换为主名称将jest.genMockFromModule改为jest.createMockFromModule将jest.SpyInstance改为jest.Spied修正jest.mock路径的大小写。运行测试并修复失败修复因 matcher 别名移除导致的断言报错重新生成受格式化变化影响的快照Errorcause、React 空字符串、goo.gl 链接等关注 TypeScript 编译错误——它们会引导你更新废弃 API 用法并修正因CalledWith类型推断变严格而暴露出的参数不匹配问题留意未处理 Promise 拒绝的判定变化必要时通过waitForUnhandledRejections选项调整行为。【免费下载链接】jestDelightful JavaScript Testing.项目地址: https://gitcode.com/gh_mirrors/je/jest创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表