为啥 Jest --runInBand 会加快测试速度?

Posted

技术标签:

【中文标题】为啥 Jest --runInBand 会加快测试速度?【英文标题】:Why does Jest --runInBand speed up tests?为什么 Jest --runInBand 会加快测试速度? 【发布时间】:2017-10-07 11:14:12 【问题描述】:

我读到--runInBand 标志在 CI 服务器上将 Jest 测试持续时间加快了 50%。除了它允许测试在同一个线程中按顺序运行之外,我真的无法在网上找到关于该标志的作用的解释。

为什么在同一个线程中按顺序运行测试会使其更快?直觉上,这不应该让它变慢吗?

【问题讨论】:

【参考方案1】:

当您在多线程中运行测试时,jest 会为每个线程创建一个缓存。当您使用--runInBand 运行时,jest 使用一个缓存存储进行所有测试。

我在运行 20 个相同的测试文件后发现它,首先使用密钥 --runInBand,第一次测试需要 25 秒,接下来的相同测试每次需要 2-3 秒。

当我在没有--runInBand 键的情况下运行测试时,每个相同的测试文件都会在 25 秒内执行。

【讨论】:

那么在本地运行测试的时候使用--runInBand来加速测试运行会有好处吗?我们使用jest --coverage --runInBand --no-cache 进行持续集成。 您还应该在 codeepic 的命令中添加 --ci 标志。 jestjs.io/docs/en/cli#ci【参考方案2】:

阅读您的链接页面和其他一些相关来源(如this github issue)一些用户发现:

...使用--runInBand 有助于在资源有限的环境中。

...--runInBand 将我们的测试从 >1.5 小时(实际上我不知道多长时间,因为 Jenkins 在 1.5 小时超时)缩短到 4 分钟左右。 (注意:我们的构建服务器确实资源匮乏

正如我们所见,尽管这些用户的计算机资源有限,但他们的计算机性能有所提高。如果我们从docs 中读取--runInBand 标志的作用,它会说:

别名:-i。在当前进程中连续运行所有测试,而不是创建运行测试的子进程的工作池。这对于调试很有用。

因此,考虑到这些 cmets 和文档,我认为性能的提高是由于现在该进程在单个线程中运行。这极大地帮助了资源有限的计算机,因为它不必花费内存和时间来处理和处理线程池中的多个线程,这对于其有限的资源而言可能被证明过于昂贵。

但是,我相信只有当您使用的机器资源有限时才会出现这种情况。如果您使用更“强大”的机器(即:多个内核、不错的 RAM、SSD 等),使用多个线程可能会比运行单个线程更好。

【讨论】:

我在 i5-3570 @ 3.40GHz 和 16 GB RAM + SSD 上,我看到使用 --runInBand 的性能得到了显着提升 - 这不是最先进的计算机,但我不确定我会称它为资源有限的计算机。对我来说为什么 runInBand 更快没有任何意义。 请注意,虽然--runInBand 也可能会减慢运行速度,例如。如果您有许多测试套件,最好使用--maxWorkers--maxParallel 并将其设置为核心/线程数。在我们的 Jenkins CI(4 核,8Gb)中,我们使用 --runInBand 进行了 50 分钟的单元测试,在将其设置为 --maxParallel=4 后下降到 20 分钟。如果没有任何这些设置,它就会耗尽内存 (OOM),因为它会产生许多线程(这两种方法都阻止了)。 @Markus 感谢您的反馈和分享您的经验。我仍然看到的缺点是调试......正如我们所知,调试线程和并行的东西可能很乏味,并且在单线程中运行对调试有很大帮助。而且,就像 OP 所面临的情况和他们所指的来源一样,ruuninband 极大地帮助了那些买不起多核或资源非常有限的人......如果你没有有限的资源,那么一定要使用你能得到的所有力量:) @DarkCygnus 完全同意,如果您只有 1 个核心,则在带内运行是有意义的。只是想强调它不是圣杯,尤其是如果您有 2 个或更多内核并指出替代方案。 多么糟糕的选项。 --singleThread 可能更清楚。即使在 8 核 i9、32Gb MacBookPro 上,此选项也始终将测试套件时间从 30 秒缩短到 23 秒。

以上是关于为啥 Jest --runInBand 会加快测试速度?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法用 Jest 顺序运行一些测试?

为啥 Jest 在测试“Colyseus”游戏时会出现这个错误?

为啥基于 jest 的单元测试现在会导致 0% 的测试覆盖率?

为啥我的文件夹名称会影响 `npm test`、Jest 和 Babel?

为啥 jest 寻找不再存在的测试文件?

为啥 Jest 不让我使用节点测试环境,即使他们自己更改了它?