只需更改一个设置,即可使 Jest 测试速度提高 20%

2025-05-28

只需更改一个设置,即可使 Jest 测试速度提高 20%

最初发布于ivantanev.com

TL;DR

当您使用Jest作为测试运行器时,--maxWorkers=50%在大多数情况下,传递该选项可以加快测试速度。对于监视模式,请使用--maxWorkers=25%,对于 CI,请使用 禁用 Jest 工作器--runInBand。您可以尝试不同的百分比,并根据具体设置进行微调。

// package.json
{
  "scripts": {
    // standalone Jest
    "test": "jest --maxWorkers=50%",
    "test:watch": "jest --watch --maxWorkers=25%",
    "test:ci": "jest --runInBand",

    // or with Create React App
    "test": "react-scripts test --watchAll=false --maxWorkers=50%",
    "test:watch": "react-scripts test --maxWorkers=25%",
    "test:ci": "react-scripts test --watchAll=false --runInBand"
  }
}
Enter fullscreen mode Exit fullscreen mode

更新时间:2021-03-29

虽然很多人反馈了不错的结果,但我也发现一些迹象表明,在没有超线程的旧款英特尔 CPU 上,上述设置会导致性能下降。您应该针对您的具体设置进行基准测试和验证。

Jest 如何选择要使用的 worker 数量

Jest 测试运行器Create React App默认提供)开箱即用,但运行效果不佳。

默认情况下,Jest 会运行在所有可用的 CPU 线程上,其中一个线程用于 cli 进程,其余线程用于测试工作线程。在监视模式下,它将使用一半的可用 CPU 线程。

然而,这导致我测试的所有系统的性能都不太理想。

我们可以--maxWorkers通过提供线程数量或可用系统线程的百分比来进行调整。我更喜欢使用百分比,因为通常很容易找到一个适用于不同 CPU 的多个系统的值。

使用 --maxWorkers=50% 对 Jest 进行基准测试

以下是所用测试套件的统计数据。这是一个 React 应用,主要包含单元测试:

Test Suites: 43 passed, 43 total
Tests:       1 skipped, 258 passed, 259 total
Snapshots:   2 passed, 2 total
Enter fullscreen mode Exit fullscreen mode

以下是在 Intel i9-9900KS(5GHz/8 核 16 线程)上的测试结果:
加速 21%。

$ hyperfine 'npm test' 'npm test -- --maxWorkers=50%'
Benchmark #1: npm test
  Time (mean ± σ):      4.763 s ±  0.098 s    [User: 49.334 s, System: 5.996 s]
  Range (min … max):    4.651 s …  4.931 s    10 runs

Benchmark #2: npm test -- --maxWorkers=50%
  Time (mean ± σ):      3.925 s ±  0.044 s    [User: 27.776 s, System: 4.028 s]
  Range (min … max):    3.858 s …  3.973 s    10 runs

Summary
  'npm test -- --maxWorkers=50%' ran
    1.21 ± 0.03 times faster than 'npm test'
Enter fullscreen mode Exit fullscreen mode

以下是 2016 款 13 英寸 MacBook Pro(3.3GHz / 2 核 4 线程)的测试结果:
加速 14%。

$ hyperfine 'npm test' 'npm test -- --maxWorkers=50%'
Benchmark #1: npm test
  Time (mean ± σ):     14.380 s ±  0.230 s    [User: 22.869 s, System: 3.689 s]
  Range (min … max):   14.049 s … 14.807 s    10 runs

Benchmark #2: npm test -- --maxWorkers=50%
  Time (mean ± σ):     12.567 s ±  0.213 s    [User: 19.628 s, System: 3.290 s]
  Range (min … max):   12.258 s … 12.942 s    10 runs

Summary
  'npm test -- --maxWorkers=50%' ran
    1.14 ± 0.03 times faster than 'npm test'
Enter fullscreen mode Exit fullscreen mode

最后,2020 款 M1 MacBook Air:
加速 12%。

$ hyperfine 'npm test' 'npm test -- --maxWorkers=50%'
Benchmark #7: npm run test
  Time (mean ± σ):      5.833 s ±  0.025 s    [User: 30.257 s, System: 6.995 s]
  Range (min … max):    5.813 s …  5.861 s    3 runs

Benchmark #4: npm test -- --maxWorkers=50%
  Time (mean ± σ):      5.216 s ±  0.060 s    [User: 19.301 s, System: 3.523 s]
  Range (min … max):    5.179 s …  5.285 s    3 runs

Summary
  'npm test -- --maxWorkers=50%' ran
    1.12 ± 0.01 times faster than 'npm test'
Enter fullscreen mode Exit fullscreen mode

与其他程序一起运行怎么样?

衡量这一点比较困难,但我注意到,--maxWorkers=25%在我的用例中,使用 with 运行效果最佳。这对于代码监控/热重载以及并行运行提交钩子来说,
性能最佳。test:watchhusky

那么 CI 怎么样?

根据我和其他人的经验,--runInBand这可能是 CI 运行最快的选择。

它有什么--runInBand作用?官方文档是这样描述的:

在当前进程中串行运行所有测试,而不是创建运行测试的子进程的工作池。这对于调试非常有用。

事实证明,它在 CI 等资源受限的环境中也很有用,其中工作进程的开销高于并行运行测试的加速。

为给定的测试套件/系统找到最佳线程数

编写一个小脚本来找到适合您特定用例的最佳线程数很容易:

export MAX_WORKERS=15; hyperfine --parameter-scan num_threads 1 $MAX_WORKERS 'npm run test -- --maxWorkers={num_threads}' -m 3 -w 1
Enter fullscreen mode Exit fullscreen mode

以下是在 Intel i9-9900KS(5GHz/8 核 16 线程)上的测试结果:

Summary
  'npm run test:jest -- --maxWorkers=7' ran
    1.01 ± 0.01 times faster than 'npm run test:jest -- --maxWorkers=8'
    1.02 ± 0.02 times faster than 'npm run test:jest -- --maxWorkers=6'
    1.04 ± 0.02 times faster than 'npm run test:jest -- --maxWorkers=5'
    1.05 ± 0.02 times faster than 'npm run test:jest -- --maxWorkers=9'
    1.08 ± 0.03 times faster than 'npm run test:jest -- --maxWorkers=10'
    1.11 ± 0.02 times faster than 'npm run test:jest -- --maxWorkers=11'
    1.11 ± 0.02 times faster than 'npm run test:jest -- --maxWorkers=4'
    1.18 ± 0.02 times faster than 'npm run test:jest -- --maxWorkers=13'
    1.19 ± 0.02 times faster than 'npm run test:jest -- --maxWorkers=14'
    1.21 ± 0.04 times faster than 'npm run test:jest -- --maxWorkers=12'
    1.23 ± 0.02 times faster than 'npm run test:jest -- --maxWorkers=15'
    1.25 ± 0.02 times faster than 'npm run test:jest -- --maxWorkers=3'
    1.58 ± 0.02 times faster than 'npm run test:jest -- --maxWorkers=2'
    2.55 ± 0.04 times faster than 'npm run test:jest -- --maxWorkers=1'
Enter fullscreen mode Exit fullscreen mode

如你所见,本例中的最佳工人数量是 7 人,而不是50%我们预期的 8 人。然而,两者之间的差异在误差范围内,并且50%更加灵活。

结论

通过调整,可以轻松提升 Jest 的开箱即用性能maxWorkers。如果您决定亲自测试,Hyperfine会让测试变得非常容易。

希望以上内容对您有所帮助!欢迎通过 Twitter 或@VanTanev联系我

祝您黑客愉快!

文章来源:https://dev.to/vantanev/make-your-jest-tests-up-to-20-faster-by-change-a-single-setting-i36
PREV
Git 中分支和提交命名的简化约定
NEXT
开发人员的 7 个 UI 设计基础知识