跳至主内容
版本:29.7

故障排除

非官方测试版翻译

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

哎呀,遇到问题了吗?本指南将帮助您解决 Jest 相关的问题。

测试失败且原因不明

尝试使用 Node 内置的调试支持。在您的测试文件中添加 debugger; 语句,然后在项目目录下运行:

node --inspect-brk node_modules/.bin/jest --runInBand [any other arguments here]
or on Windows
node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand [any other arguments here]

这将在 Node 进程中运行 Jest,外部调试器可以连接到此进程。请注意,进程将暂停直到调试器连接成功。

要在 Google Chrome(或任何基于 Chromium 的浏览器)中进行调试,请打开浏览器并访问 chrome://inspect,然后点击"Open Dedicated DevTools for Node",这将显示可连接的 Node 实例列表。运行上述命令后,点击终端中显示的地址(通常是类似 localhost:9229 的地址),即可使用 Chrome 开发者工具调试 Jest。

Chrome 开发者工具将会显示,并且在 Jest CLI 脚本的第一行设置断点(这样可以让您有时间打开开发者工具,防止 Jest 提前执行)。点击屏幕右上角的"播放"按钮继续执行。当 Jest 执行到包含 debugger 语句的测试时,执行将暂停,您可以检查当前作用域和调用堆栈。

备注

--runInBand 命令行选项确保 Jest 在同一个进程中运行测试,而不是为每个测试生成单独进程。通常 Jest 会跨进程并行运行测试,但同时调试多个进程比较困难。

在 VS Code 中调试

有多种方式可以使用 Visual Studio Code 内置的调试器来调试 Jest 测试。

要附加内置调试器,请按上述方式运行测试:

node --inspect-brk node_modules/.bin/jest --runInBand [any other arguments here]
or on Windows
node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand [any other arguments here]

然后使用以下 launch.json 配置附加 VS Code 调试器:

{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach",
"port": 9229
}
]
}

要自动启动并附加到运行测试的进程,请使用以下配置:

{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Jest Tests",
"type": "node",
"request": "launch",
"runtimeArgs": [
"--inspect-brk",
"${workspaceRoot}/node_modules/.bin/jest",
"--runInBand"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}

或在 Windows 上使用:

{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Jest Tests",
"type": "node",
"request": "launch",
"runtimeArgs": [
"--inspect-brk",
"${workspaceRoot}/node_modules/jest/bin/jest.js",
"--runInBand"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}

如果您使用 Facebook 的 create-react-app,可以使用以下配置调试 Jest 测试:

{
"version": "0.2.0",
"configurations": [
{
"name": "Debug CRA Tests",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
"args": [
"test",
"--runInBand",
"--no-cache",
"--env=jsdom",
"--watchAll=false"
],
"cwd": "${workspaceRoot}",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}

更多关于 Node 调试的信息可在此查阅

在 WebStorm 中调试

WebStorm 内置支持 Jest。请阅读在 WebStorm 中使用 Jest 进行测试了解更多。

缓存问题

转换脚本已修改或 Babel 已更新,但变更未被 Jest 识别?

请使用 --no-cache 重试。Jest 会缓存转换后的模块文件以加速测试执行。如果使用自定义转换器,建议添加 getCacheKey 函数,例如 Relay 中的实现

Promise 未解决

如果 Promise 始终未解决,可能会抛出以下错误:

- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

这通常由冲突的 Promise 实现引起。建议替换全局 Promise 实现,例如使用 globalThis.Promise = jest.requireActual('promise');,或统一使用的 Promise 库。

如果测试运行时间较长,建议通过调用 jest.setTimeout 增加超时时间。

jest.setTimeout(10_000); // 10 second timeout

Watchman 问题

尝试使用 --no-watchman 参数运行 Jest,或将配置中的 watchman 选项设为 false

另请参阅 Watchman 故障排除指南

测试在 Docker 和/或 CI 服务器上运行极慢

虽然 Jest 在现代多核 SSD 设备上通常速度极快,但用户反馈在某些环境下会出现性能问题(案例1案例2)。

根据问题分析,通过顺序执行测试可将速度提升最高 50%。

使用 --runInBand 参数在单线程中运行测试:

# Using Jest CLI
jest --runInBand

# Using your package manager's `test` script (e.g. with create-react-app)
npm test -- --runInBand

在 Travis-CI 等持续集成服务器上,将 worker 池最大数设为 ~4 可显著加速(Travis-CI 开源项目免费版仅提供 2 个 CPU 核心)。

# Using Jest CLI
jest --maxWorkers=4

# Using your package manager's `test` script (e.g. with create-react-app)
npm test -- --maxWorkers=4

若使用 GitHub Actions,可通过 github-actions-cpu-cores 自动检测 CPU 核心数并传递给 Jest。

- name: Get number of CPU cores
id: cpu-cores
uses: SimenB/github-actions-cpu-cores@v2
- name: run tests
run: yarn jest --max-workers ${{ steps.cpu-cores.outputs.count }}

还可使用 shard 参数在多台机器上并行运行测试。

coveragePathIgnorePatterns 似乎未生效

请确认未使用 babel-plugin-istanbul 插件。Jest 已集成 Istanbul 的代码覆盖率检测功能,而使用 babel-plugin-istanbul 会使 Babel 处理的所有文件都插入覆盖率检测代码,导致 coveragePathIgnorePatterns 失效。

测试用例定义规范

Jest 要求测试用例必须同步定义才能正确收集测试。

举个例子来说明为什么会出现这种情况,假设我们编写了如下测试:

// Don't do this it will not work
setTimeout(() => {
it('passes', () => expect(1).toBe(1));
}, 0);

当 Jest 运行测试以收集 tests 时,因测试定义被延迟到事件循环的下个周期,导致无法检测到测试用例。因此在使用 test.each 时,不能在 beforeEach / beforeAll 中异步设置参数表。

问题仍未解决?

请访问帮助中心