跳至主要内容
版本:29.7

故障排除

糟糕,出问题了?使用本指南解决 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,然后单击“为 Node 打开专用 DevTools”,这将为您提供可连接的可用节点实例列表。在运行上述命令后,单击终端中显示的地址(通常类似于 localhost:9229),您将能够使用 Chrome 的 DevTools 调试 Jest。

将显示 Chrome 开发者工具,并且将在 Jest CLI 脚本的第一行设置断点(这样做是为了让您有时间打开开发者工具,并防止 Jest 在您有时间这样做之前执行)。单击屏幕右上角看起来像“播放”按钮的按钮以继续执行。当 Jest 执行包含 debugger 语句的测试时,执行将暂停,您可以检查当前范围和调用堆栈。

注意

--runInBand CLI 选项确保 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 中的 getCacheKey

未解决的 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 的现代多核计算机上非常快,但它可能在某些设置上很慢,正如我们的用户 发现的 那样

根据 发现,缓解此问题并提高速度(最多 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 等持续集成服务器上加快测试执行时间的另一种方法是将最大工作池设置为 ~4。具体来说,在 Travis-CI 上,这可以将测试执行时间缩短一半。注意:适用于开源项目的 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,因此也会告诉 Istanbul 使用覆盖率收集来检测哪些文件。当使用 babel-plugin-istanbul 时,每个由 Babel 处理的文件都将包含覆盖率收集代码,因此它不会被 coveragePathIgnorePatterns 忽略。

定义测试

测试必须同步定义,以便 Jest 能够收集您的测试。

例如,假设我们编写了以下测试

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

当 Jest 运行您的测试以收集 test 时,它将找不到任何测试,因为我们已将定义设置为在事件循环的下一个刻度异步发生。这意味着当您使用 test.each 时,您不能在 beforeEach / beforeAll 中异步设置表格。

仍然无法解决?

参见 帮助