Jest 疑难解答

2021-09-18 20:38 更新

哦哦,出事了?使用本指南解决 Jest 的问题。

找不到测试失败的原因

请尝试使用 Node 内置的调试功能。注意:这只适用于Node.js 8+。

在你的单元测试中添加一条 ​debugger;​语句,然后在项目目录中执行:

  1. node --inspect-brk node_modules/.bin/jest --runInBand [any other arguments here]
  2. or on Windows
  3. 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”,这将为你提供可以连接的可用节点实例列表。​localhost:9229​运行上述命令后,点击终端中显示的地址(通常类似于),你将可以使用 Chrome 的 DevTools 调试 Jest。

Chrome开发者工具将会被显示,并在Jest CLI脚本的第一行设置断点(这样做是为了给你时间打开开发者工具,并在你有时间之前阻止Jest执行)。

点击开发者工具中右上方调试菜单栏中的“开始调试” 按钮,让代码继续执行。 当 Jest 执行到添加了​debugger; ​语句的单元测试时,执行就会暂停,此时,你可以检查当前的值域和调用栈。

注意: ​--runInBand​ cli 选项确保 Jest 在同一进程中运行测试,而不是为单个测试生成进程。通常情况下,Jest 并行化测试会跨进程执行,但是很难同时调试多个进程。

在 VS Code 中调试

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

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

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

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

  1. {
  2. "version": "0.2.0",
  3. "configurations": [
  4. {
  5. "type": "node",
  6. "request": "attach",
  7. "name": "Attach",
  8. "port": 9229
  9. }
  10. ]
  11. }

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

  1. {
  2. "version": "0.2.0",
  3. "configurations": [
  4. {
  5. "name": "Debug Jest Tests",
  6. "type": "node",
  7. "request": "launch",
  8. "runtimeArgs": [
  9. "--inspect-brk",
  10. "${workspaceRoot}/node_modules/.bin/jest",
  11. "--runInBand"
  12. ],
  13. "console": "integratedTerminal",
  14. "internalConsoleOptions": "neverOpen",
  15. "port": 9229
  16. }
  17. ]
  18. }

或以下适用于 Windows:

  1. {
  2. "version": "0.2.0",
  3. "configurations": [
  4. {
  5. "name": "Debug Jest Tests",
  6. "type": "node",
  7. "request": "launch",
  8. "runtimeArgs": [
  9. "--inspect-brk",
  10. "${workspaceRoot}/node_modules/jest/bin/jest.js",
  11. "--runInBand"
  12. ],
  13. "console": "integratedTerminal",
  14. "internalConsoleOptions": "neverOpen",
  15. "port": 9229
  16. }
  17. ]
  18. }

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

  1. {
  2. "version": "0.2.0",
  3. "configurations": [
  4. {
  5. "name": "Debug CRA Tests",
  6. "type": "node",
  7. "request": "launch",
  8. "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
  9. "args": ["test", "--runInBand", "--no-cache", "--env=jsdom"],
  10. "cwd": "${workspaceRoot}",
  11. "protocol": "inspector",
  12. "console": "integratedTerminal",
  13. "internalConsoleOptions": "neverOpen"
  14. }
  15. ]
  16. }

更多关于 Node 调试的信息,可以查看这里

在 WebStorm 中调试

WebStorm 中调试 Jest 测试的最简单方法是使用​Jest run/debug configuration​. 它将启动测试并自动附加调试器。

在 WebStorm 菜单中Run选择​Edit Configurations...​。然后单击​+​并选择Jest。(可选)指定 Jest 配置文件、附加选项和环境变量。保存配置,在代码中放置断点,然后点击绿色调试图标开始调试。

如果你使用 Facebook 的create-react-app,请在 Jest 运行/调试配置react-scripts中的 Jest 包字段中指定包的路径并添加​--env=jsdom​到 Jest 选项字段。

缓存问题

转换脚本已更改或 Babel 已更新并且 Jest 无法识别更改?

尝试使用​ --no-cache ​选项。 Jest 会缓存转换的模块文件来加速测试的执行。如果你在使用自己的自定义转换器,请考虑将GETCaseKEY函数添加到它:getCacheKey in Relay.

未返回的 Promises

如果一个 Promise 并未返回任何东西(no resolve)你会看到类似于下边的报错:

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

通常这是由冲突的Promise 实现引发的。 考虑用自己的替代全局承诺实现,例如Global,​Posiv= Jest.RealEngor(“promise”);​和/或将使用过的Promise库合并为单个库。

如果你的测试长时间运行,可能需要考虑通过调用来增加超时时间 jest.setTimeout

  1. jest.setTimeout(10000); // 10 second timeout

看门狗问题

尝试运行 Jest--no-watchman或将watchman配置选项设置为false.

更多详情,查看 看门狗疑难解答.

Docker 和/或 持续集成(CI,Continuous Integration)服务器中执行 Jest 测试极慢。

虽然 Jest 是大部分时间非常快的现代多核计算机具有快速的固态硬盘,它可能是缓慢的某些设置,已经被我们的用户发现了。

根据调查结果,缓解此问题并将速度提高多达 50% 的一种方法是按顺序运行测试。

达成上述目的,可以使用​--runInBand​选项:

  1. # Using Jest CLI
  2. jest --runInBand
  3. # Using yarn test (e.g. with create-react-app)
  4. yarn test --runInBand

在 Travis-CI 等持续集成服务器上加快测试执行时间的另一种选择是将最大工作池设置为 ~ 4。特别是在 Travis-CI 上,这可以将测试执行时间减少一半。注意:可用于开源项目的 Travis CI免费计划仅包含 2 个 CPU 内核。

  1. # Using Jest CLI
  2. jest --maxWorkers=4
  3. # Using yarn test (e.g. with create-react-app)
  4. yarn test --maxWorkers=4

coveragePathIgnorePatterns 似乎没有任何影响。

确保你没有使用该babel-plugin-istanbul插件。Jest 包装了Istanbul,因此也告诉Istanbul 哪些文件要使用覆盖率收集进行检测。使用时babel-plugin-istanbul,Babel 处理的每个文件都会有覆盖率收集代码,因此不会被​coveragePathIgnorePatterns​.

定义测试

必须同步定义测试,Jest 才能收集你的测试。

举个例子来说明为什么会这样,假设我们写了一个这样的测试:

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

当 Jest 运行你的测试以收集tests 时,它不会找到任何内容,因为我们已将定义设置为在事件循环的下一个滴答声中异步发生。

注意:这意味着当你使用test.each时,你不能在beforeEach/中异步设置表beforeAll。

尚未解决问题?

点 这里 查看帮助


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号