开玩笑,简单的测试很慢

我使用 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
}
}

我的 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()
);

这是我的简单测试:

fdescribe('RichTextEditorComponent', () => {
it('should be fast', () => {
expect(true).toBeTruthy();
});
});

有人知道为什么要花9秒多吗? enter image description here

74581 次浏览

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

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

我也在我的 Angular 项目中使用 Jest,我不确定这是一个好的解决方案。

配置测试模块时,可以使用 NO_ERRORS_SCHEMA,而不必在 declarations中添加所有嵌套组件来编译要测试的组件。

beforeEach(async () => {
return TestBed.configureTestingModule({
declarations: [
MyComponent
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
});

您使用 Jest 进行的测试是单元测试,因此使用该解决方案,您将只测试您的组件。 如果您想要测试组件之间的交互,您将使用量角器或木偶师进行端到端的测试。

阅读以下两个链接:

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. 升级玩笑版本 好像有些 bug 让某些版本变慢了 Https://github.com/facebook/jest/pull/8046

    注意: yarn upgrade服从 ~ 和 ^ 版本意符, 如果你知道你在做什么,你可能只是想删除和重新添加 yarn remove jest yarn add -D jest 这只会给你带来最新的消息

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

"jest": {
"testEnvironment": "node"
}
  1. 同步运行测试. . 允许 jest 优化?

添加 --runInBand选项

  1. 设置最大工作人数可能会让它更快?

添加 --maxWorkers=4选项

在我的例子中,我升级了 jest 版本,开始使用—— watch 和—— runInBand,并在主机上运行,而不是通过 docker,测试时间从2分钟增加到10秒。我不知道我到底有什么问题。

另一种可能性是,这个玩笑是缓慢的。有一个 这个问题,并没有完全解决。

有各种 讨论的解决办法。它们由 设定 isolatedModules=true--maxWorkers=1组成。也就是说,在 jest.config.js

'use strict';


module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
globals: {
'ts-jest': {
isolatedModules: true
}
},
}

然后逃跑

yarn test --maxWorkers=1

也许值得一试。或者,也可以放弃开玩笑,使用巴别塔翻译。

我解决了同样的问题,通过安装 jest 作为全球

npm install -g jest@26.0

下面是一些具有相同项目和相同测试用例的基准测试结果

Local -win10 version 2004—————————— node-14.7.0—— < strong > 11.847 s

Global -win10 version 2004—————————— node-14.7.0—— < strong > 0.907 s

Global -win10 version 2004-Wsl/ubuntu-18.04-node-14.7.0-< strong > 0.469 s

如果有人需要处理测试套件执行缓慢的问题,请将版本升级到25或更高版本。玩笑版本24运行缓慢。

Https://jestjs.io/blog/2020/01/21/jest-25#performance-improvements [ jest-25 # 绩效改善][1]

2022年——在你的 jest.config 中添加:

globals: {
"ts-jest": {
isolatedModules: true
}
}

然后逃跑

yarn test

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

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

jest.config.js中,将 Jest 配置为使用 SWC:

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

用途

yarn jest --runInBand

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

备选方案: ESBuild

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

yarn add -D esbuild-jest esbuild

jest.config.js中,将 Jest 配置为使用 esbuild

module.exports = {
transform: {
"^.+\\.(t|j)sx?$": ["esbuild-jest"],
},
};

加速,玩笑的启发

我的测试运行非常缓慢,由于 这个问题与伪造者(版本: 7.3.0)。

使用 const { faker } = require('@faker-js/faker/locale/en_US');而不是 const { faker } = require('@faker-js/faker');可以将 request 语句的速度提高约50秒。

我花了不少时间才找到那个混蛋

最终,对我有效的方法是对 jest 测试进行分析,并通过分析来确定是什么导致了 jest 启动缓慢。您可以使用 这个视频来帮助。

对我来说,这是 @mui/icons-material库。卸载后,运行一个单一的文件从5s 到2s。

我发现了另一种选择:

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


// Directly importing speeds up by 3s
import ExpandMore from "@mui/icons-material/ExpandMore"

这个过程可以帮助您确定根本原因,但这最终不是一个修复。

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

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

使用 docker 和为 node_modules安装卷导致测试非常缓慢。

移除 node_modules上的安装卷可以加快测试约60秒。

有关这方面的详细信息,请参阅以下链接。

  1. Https://stackoverflow.com/a/47564342/9530790
  2. Https://stackoverflow.com/a/49081609/9530790

在使用 jetbrain 的时候,有一个文件观察器使我的测试速度降低了100% 。

我注意到这一点,当我关闭我的喷气机大脑和我的测试运行超过100% 的速度。

降级形式的笑话 ^29.x.x^26.6.3超过一倍我的笑话速度更合理的几秒钟而不是两位数秒。

以防万一,如果您的测试用例由于所使用的硬件而花费了太长的时间。

你可能会得到这样的错误:

  thrown: "Exceeded timeout of 5000 ms for a hook.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."

为了避免这个错误,您可以使用 --testTimeout <TIME_IN_MILLI_SECONDS>选项增加命令行中的超时时间,例如,我在这里使用了50秒

jest --testTimeout 50000

注意: 默认超时时间为5000 ms (5秒)。