开玩笑 - 简单的测试很慢

Tuc*_*ker 37 javascript typescript jestjs angular

我正在使用Jest测试一个角度应用程序,它需要很长时间才能运行简单的测试,我似乎无法弄清楚原因.

我的Jest设置package.json如下:

"jest": {
  "modulePaths": [
    "<rootDir>/src",
    "<rootDir>/node_modules"
  ],
  "testPathIgnorePatterns": [
    ".git/.*",
    "node_modules/.*"
  ],
  "transformIgnorePatterns": [
    "node_modules/.*",
    ".*\\.js"
  ],
  "setupTestFrameworkScriptFile": "<rootDir>/src/setupJest.js",
  "preset": "jest-preset-angular",
  "testEnvironment": "jsdom",
  "testRegex": "src/app/.*\\.spec\\.ts$",
  "moduleFileExtensions": [
    "ts",
    "js",
    "json"
  ],
  "verbose": true,
  "cacheDirectory": ".jest-cache",
  "coveragePathIgnorePatterns": [
    ".*\\.(shim\\.ngstyle|ngfactory)\\.ts"
  ],
  "globals": {
    "ts-jest": {
      "tsConfigFile": "./tsconfig.json"
    },
    "__TRANSFORM_HTML__": true
  }
}
Run Code Online (Sandbox Code Playgroud)

我的Jest安装文件:

'use strict';
require('core-js/es6/reflect');
require('core-js/es7/reflect');
require('zone.js');
require('zone.js/dist/proxy.js');
require('zone.js/dist/sync-test');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
require('jest-zone-patch');

const getTestBed = require('@angular/core/testing').getTestBed;
const BrowserDynamicTestingModule = require('@angular/platform-browser-dynamic/testing').BrowserDynamicTestingModule;
const platformBrowserDynamicTesting = require('@angular/platform-browser-dynamic/testing')  .platformBrowserDynamicTesting;

getTestBed().initTestEnvironment(
    BrowserDynamicTestingModule,
    platformBrowserDynamicTesting()
);
Run Code Online (Sandbox Code Playgroud)

这是我的简单测试:

fdescribe('RichTextEditorComponent', () => {
  it('should be fast', () => {
    expect(true).toBeTruthy();
  });
});
Run Code Online (Sandbox Code Playgroud)

有没有人知道为什么这需要9秒以上? 在此输入图像描述

ger*_*ert 26

2023 年- 试试这个:

globals: {
  "ts-jest": {
    isolatedModules: true
  }
}
Run Code Online (Sandbox Code Playgroud)

并运行

yarn test
Run Code Online (Sandbox Code Playgroud)

  • 有关原因的更多信息? (19认同)
  • 它跳过 TS 检查+其他一些东西:https://huafu.github.io/ts-jest/user/config/isolatedModules (2认同)
  • 如果您收到弃用警告,请改用: `transform: { "^.+\\.(t|j)sx?$": ['ts-jest', {isolatedModules: true }] }` (2认同)

Ali*_*i80 26

解决方案:(SWC快速网络编译器)

ts-jest最有可能减慢测试速度。

SWC是直接替代方案,用 . 编写Rust并且速度超快对我来说提高了 10 倍以上。关联

安装

# if you use npm
npm i -D @swc/core @swc/jest

# if you use yarn
yarn add -D @swc/core @swc/jest
Run Code Online (Sandbox Code Playgroud)

在内部jest.config.js,配置 Jest 以使用 SWC:

module.exports = {
  transform: {
    "^.+\\.(t|j)sx?$": ["@swc/jest"],
  },
};
Run Code Online (Sandbox Code Playgroud)

用法

yarn jest --runInBand
Run Code Online (Sandbox Code Playgroud)

注意:jest 版本 28 目前不稳定。我用27.0.4

替代方案:ESBuild

使用也可以使用esbuild写成的Go,也很快。(与swc类似的性能)

yarn add -D esbuild-jest esbuild
Run Code Online (Sandbox Code Playgroud)

在里面jest.config.js,配置 Jest 以使用 esbuild

yarn jest --runInBand
Run Code Online (Sandbox Code Playgroud)

灵感来自加速玩笑

  • 这种方法比使用 ts-jest 快得多。考虑到您的 IDE 将进行实时类型检查,我认为没有必要在开发过程中的每次测试运行中都运行 typescript。只需确保在显式构建/CI 期间运行打字稿,以确保类型错误不会消失。 (3认同)

use*_*610 23

另一种可能性是 ts-jest 很慢。有一个关于那个问题,并没有完全解决。

讨论了各种变通方法。它们包括设置isolatedModules=true--maxWorkers=1。也就是说,在jest.config.js

'use strict';

module.exports = {
    preset: 'ts-jest',
    testEnvironment: 'node',
    globals: {
        'ts-jest': {
            isolatedModules: true
        }
    },
}
Run Code Online (Sandbox Code Playgroud)

并运行

yarn test --maxWorkers=1
Run Code Online (Sandbox Code Playgroud)

可能值得一试。或者,可以放弃 ts-jest 并使用 babel 转译。

  • 在 Linux 机器上也进行了缓慢的测试。“isolatedModules”是关键。没有设置`maxWorkers=1` (9认同)
  • 请注意“isolatedModules: true”将禁用类型检查 (9认同)
  • 使用 `maxWorkers` 效果很好,我的测试时间从 20 秒减少到大约 3 秒:)) (7认同)
  • 从 `ts-jest` 29 开始,在 `globals` 键下设置此选项似乎已被弃用。[现在](https://kulshekhar.github.io/ts-jest/docs/getting-started/options/isolatedModules)看来你设置了一个“transform”选项。 (5认同)
  • @MaximMazurok [来源](https://huafu.github.io/ts-jest/user/config/isolatedModules) (2认同)

小智 21

阅读这两个链接:

https://itnext.io/how-to-make-your-sluggish-jest-v23-tests-go-faster-1d4f3388bcdd https://github.com/facebook/jest/issues/7963

以下是需要考虑的事项列表。它们并非针对您的情况,但由于问题的标题非常笼统,我认为它们可能会帮助一定比例的访问者。它们不应该盲目尝试,它们只是研究的起点。

尝试加速你的笑话测试的事情:

  1. 在监视模式下运行 --watch

    使用 .jest 时会优化--watch

  2. 在您的主机上运行而不是在 docker 中运行?-> 我以前使用过docker exec -it <containername> yarn test,当我改用我的主机时发现它更快。

  3. 升级 jest 版本似乎有一些错误使某些版本变慢 https://github.com/facebook/jest/pull/8046

    注意:yarn upgrade遵守 ~ 和 ^ 版本符号,如果您知道自己在做什么,您可能只想删除并重新添加 yarn remove jest yarn add -D jest ,这样只会为您提供最新信息

  4. 将测试环境从 jsdom 改为 node

"jest": {
  "testEnvironment": "node"
}
Run Code Online (Sandbox Code Playgroud)
  1. 同步运行测试..允许玩笑优化吗?

添加--runInBand选项

  1. 设置最大工人可能会使其更快?

添加 --maxWorkers=4选项

就我而言,我升级了 jest 版本,开始使用 --watch 和 --runInBand 并在我的主机上而不是通过 docker 运行,我的测试时间从 2 分钟缩短到 10 秒。我不知道我的情况到底是什么问题。

  • `--runInBand` 为我修复了它。 (5认同)
  • --runInBand 和 --maxWorkers 一起没有意义。 (2认同)

Min*_*eng 6

我花了一段时间才追捕这个家伙

最终对我有用的是分析笑话测试并仔细检查以确定导致笑话启动缓慢的原因。您可以使用此视频来提供帮助。

对我来说就是图书馆@mui/icons-material。卸载后,运行单个文件从5秒缩短到2秒。

我发现的替代方案:

// Instead of destructuring like such:
import { ExpandMore } from "@mui/icons-material"

// Directly importing speeds up by 3s
import ExpandMore from "@mui/icons-material/ExpandMore"
Run Code Online (Sandbox Code Playgroud)

此过程可以帮助您确定根本原因,但这最终并不能解决问题。

相关: https: //github.com/mui/material-ui/issues/12422

相关:https ://github.com/facebook/jest/issues/10833#issuecomment-1192232331


phi*_*hil 3

我认为答案最终需要来自 Angular 团队。platformBrowserDynamicTesting 的文档很少(https://angular.io/api/platform-b ​​rowser-dynamic /testing/platformBrowserDynamicTesting)。

也许 platformBrowserDynamicTesting 会模拟浏览器并将应用程序的整个 DOM 加载到内存中。在这种情况下,Angular 应用程序(没有任何缓存的 JavaScript)需要近 10 秒的加速时间似乎是合理的。也许我的解释是错误的,但根据您的报告,看起来实际测试在 6 毫秒内运行,这似乎应该满足您对“快速测试”的要求。如果您添加另一个简单的“应该快 2”测试,我很想知道测试需要多长时间。如果总数仍低于 10 秒,则表明与 Angular platformBrowserDynamicTesting 实用程序的加速相比,您的实际测试花费的时间非常少。