为啥 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 在测试“Colyseus”游戏时会出现这个错误?
为啥基于 jest 的单元测试现在会导致 0% 的测试覆盖率?