CI运行jest --coverage时报act(...)不支持React生产构建错误
问题成因
这个报错和react-testing-library本身的支持策略无关,核心原因是你的CI环境运行测试时加载了生产构建版本的React:
- React的生产构建会主动移除测试专用的
act()校验API、开发环境警告和所有辅助测试的内部逻辑,本身就不支持运行组件测试 @testing-library/react的render方法内部默认会调用act()包裹渲染逻辑,一旦拿到的是生产版React,就会触发你看到的报错- 本地运行正常但CI报错,基本都是环境变量、Jest配置或者第三方依赖适配问题导致React误判运行环境,自动切换到了生产构建入口。结合你给出的依赖版本,最常见的触发点有三个:
- CI全局环境变量设置了
NODE_ENV=production,而你使用的Jest 26.x版本没有强制在测试阶段覆写这个变量 - 第三方依赖
jest-environment-jsdom-global@2.0.4存在已知bug,会在运行时错误覆写NODE_ENV为production - 覆盖率收集阶段的transform、babel配置错误,把React的路径别名指向了生产构建产物
- CI全局环境变量设置了
修复方案
按优先级依次操作即可:
- 强制锁定测试阶段的环境变量
首先在Jest配置文件(一般是jest.config.js)中显式指定环境,不要依赖Jest的默认值:
新建module.exports = { // 保留原有其他配置 testEnvironment: "jsdom", // 替换掉原来的jsdom-global环境 setupFiles: ["<rootDir>/test/env-lock.js"], }test/env-lock.js文件,在测试启动最前端锁死环境变量:
同时修改CI中跑测试的命令,显式传入环境变量避免全局污染:process.env.NODE_ENV = "test";# Linux/macOS CI环境 NODE_ENV=test jest --coverage # 跨平台写法,需要先安装cross-env cross-env NODE_ENV=test jest --coverage - 移除冲突的第三方测试环境依赖
直接卸载jest-environment-jsdom-global,@testing-library/react@13本身已经内置了jsdom环境需要的所有全局变量适配,不需要这个第三方包,它的旧版本bug是你这个版本组合下的高发问题。 - 检查版本兼容性
@testing-library/react@13.x仅支持React 18及以上版本,如果你的项目React版本在17及以下,要么将@testing-library/react降级到12.x版本适配,要么升级React到18版本,版本不兼容也会导致React入口加载错误。 - 排查错误的别名配置
检查Jest配置的moduleNameMapper、babel配置中是否存在手动将react、react-dom映射到*.production.min.js生产产物的规则,如果有就删除,测试场景下不要手动指定React的生产入口。
验证方式
改完配置后,可以在任意测试用例最开头加临时日志确认环境:
import * as React from 'react'; test('check env', () => { console.log('当前NODE_ENV:', process.env.NODE_ENV); console.log('React act方法是否存在:', typeof React.act === 'function'); })
运行测试如果日志输出NODE_ENV为test、act方法存在,说明环境配置正确,原报错会自动消失。
注意:不存在“在生产构建版本的React上跑组件测试”的合理实践,所有组件测试都必须运行在React开发模式下,这是React本身的设计决定,不是测试库做的人为限制。
内容的提问来源于stack exchange,提问作者Jeffraux
相关产品推荐
相关产品推荐

