还有可能进一步提高吗?

问题描述 投票:0回答:1

我有一个大型 React 应用程序,在 CI 中运行了 4205 个 Jest 测试,运行所有测试需要 40 多分钟。这个时间正常吗?

版本:

NPM: 7.24.0
Node: 16.10.0
@testing-library/jest-dom: 6.4.2
@testing-library/react: 12.1.5
@testing-library/user-event: 14.5.2
jest: 29.7.0
jest-canvas-mock: 2.3.1
jest-environment-jsdom: 29.4.0
jest-junit: 16.0.0
jest-sonar: 0.2.16
jest-transform-stub: 2.0.0
jsdom: 21.1.0

jest.config.js:

module.exports = {
  clearMocks: true,
  restoreMocks: true,
  moduleNameMapper: {
    //some options
  },
  setupFiles: ["<rootDir>/buildTools/define-deprecated-global.js"],
  setupFilesAfterEnv: ["<rootDir>/buildTools/setupTests.js"],
  transform: {
    //some options
  },
  transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
  testEnvironment: "jsdom",
  testPathIgnorePatterns: ["/test.js"],
  testTimeout: 250000,
  coverageDirectory: "target/coverage",
  collectCoverage: true,
  coverageReporters: ["json", "lcov", "clover"],
  reporters: [
    //some entries
  ]
};

package.json脚本:

"test:ci": "node --max-old-space-size=8192 --experimental-vm-modules node_modules/.bin/jest --maxWorkers=20% --watchAll=false --silent",

最近我尝试将 package.json 更改为这个,但时间增加了:

"test:ci": "node --optimize-for-size --max-old-space-size=8192 --gc_interval=100 --concurrent-recompilation --no-compilation-cache --experimental-vm-modules node_modules/.bin/jest --maxWorkers=50% --watchAll=false --silent --ci",

有什么建议可以改进吗?还有更好的配置吗?除了 Jest 还有更好的替代品吗? 我知道 Node 20 修复了内存泄漏问题,但我已经尝试过 Node 20,测试时间仍然很长。

reactjs node.js jestjs react-testing-library testing-library
1个回答
0
投票

可能的帮助:

无编译缓存

我遵循了这个建议 https://dev.to/retyui/resolve-memory-leaks-caused-by-jest-with-nodejs-16x-and-18x-javascript-heap-out-of-memory-3md5并刚刚添加

--no-compilation-cache 
package.json 但我没有看到任何改进。

静态maxWorkers

我发现

--maxWorkers
在CI环境中效果不太好。我向 CI 构建请求 9000m(9 核)CPU。使用
--maxWorkers=20%
,有时测试会使用 9 个核心,有时使用 6 个核心,有时使用 4 个核心。因此,如果我请求 9000m,可能最好使用
--maxWorkers=9
--maxWorkers=7

覆盖范围

我在某处读到,在测试执行期间收集测试覆盖率可以增加测试执行时间。所以我正在考虑将测试覆盖率收集转移到 CI 的不同阶段。

为此,我相信,在 package.json 中,我需要添加另一个命令并在新的 CI 阶段中调用它:

"test:coverage": "jest --coverage"

在我的jest.config.js中,我需要在测试执行期间禁用覆盖率收集:

collectCoverage: false

承诺

我总是对 Promise 格外小心,因为我知道它们会成倍地增加我的测试时间,并且可能会导致多次不稳定的测试。 所以我:

  • 始终尝试使用
    async-await
    而不是
    .then()
  • 确保当我使用
    .then()
    ;
  • 时始终返回承诺
  • 永远
    await
    为了承诺的结果。如果我不确定一个函数是否会返回一个promise,我会检查它将返回什么样的结果,如果是一个promise,所以我显然需要
    await
  • 如无必要,切勿使用
    async
    或 / 和
    await
    。我注意到,如果代码中错误地使用了任何
    async
    或 / 和
    await
    ,则会导致测试中出现一些不稳定的情况。

为了防止其中一些情况,我在我的 .eslintrc.json:

中添加了这些规则
"require-await": "error",
"no-return-await": "error",

另一个建议是使用这个:https://www.npmjs.com/package/eslint-plugin-promise

我想知道这样做是否会增加内存泄漏(因为我有很多这样的测试):

functionToBeTested() {
  requestSomeThingToTheServer(123).then(apiResult => {
    doSomething(apiResult);
    doSomethingMore();
  });
}

test("check the Server request", (done) => {
  
  mockServerRequest((requestParams) => { //is mocking requestSomeThingToTheServer() action
    expect(requestParams).toEqual(123);
    done();
  });
  
  functionToBeTested();
});

根据此链接https://betterprogramming.pub/the-4-types-of-memory-leaks-in-node-js-and-how-to-avoid-them-part-2-f21fbda5c33b

Promise 被存储在内存中,直到它们被清除之前它们不会被清除。 要么处理要么拒绝

所以如果我在 Promise 执行期间在测试中使用

done()
,它的内存将不会被清除并且可能会出现问题?

维斯特

我正在强烈考虑迁移到 Vitest。人们说它比 Jest 更快,而且迁移似乎并不困难:

反应18

我还没有使用 React 18,但我很担心:https://github.com/testing-library/react-testing-library/issues/1235

React 18 似乎测试时间会增加更多。

一些额外信息

https://apidog.com/blog/jest-test-running-concurrently/ https://snird.medium.com/do-not-use-node-js-optimization-flags-blindly-3cc8dfdf76fd https://gist.github.com/stormwild/4bd3c1ec50ed055a363012a403b16365 https://www.npmjs.com/package/eslint-plugin-promise

© www.soinside.com 2019 - 2024. All rights reserved.