为啥我的 Minitest 测试没有并行运行?

Posted

技术标签:

【中文标题】为啥我的 Minitest 测试没有并行运行?【英文标题】:Why aren't my Minitest tests being run in parallel?为什么我的 Minitest 测试没有并行运行? 【发布时间】:2014-10-10 10:46:58 【问题描述】:

我最近才发现我的 Minitest 测试用例可以并行运行。我所要做的就是

require "minitest/hell"

所以我做到了。不幸的是,我的测试和以前完全一样。一切都会过去,它需要的时间与通常一样多。我在运行我的测试套件时检查了htop,并且只使用了一个内核。

我在随机测试中设置断点以检查测试是否实际设置为并行运行:

(byebug) Minitest::Test.test_order
:并行

那么发生了什么?


我的第一个假设是 Minitest 在决定生成多少进程时会计算 CPU 内核的数量。我有多个物理处理器(在虚拟机中),但每个处理器只有 1 个内核。我已将我的 VPS 更改为拥有两个物理处理器,每个处理器有 4 个内核,但我的测试仍未并行运行。

$ lscpu
架构:x86_64
CPU 操作模式:32 位、64 位
字节顺序:小尾数
CPU:8
在线 CPU(s) 列表:0-7
每个内核的线程数:1
每个插槽的核心数:4
插座:2
NUMA 节点:1
供应商 ID:GenuineIntel
CPU系列:6
型号:62
步进:4
CPU 频率:2600.000
BogoMIPS:5200.00
管理程序供应商:VMware
虚拟化类型:全
L1d 缓存:32K
L1i 缓存:32K
二级缓存:256K
三级缓存:20480K
NUMA node0 CPU(s): 0-7

【问题讨论】:

【参考方案1】:

Minitest 使用线程而不是进程来执行并行测试。

由于 MRI(标准 Ruby 解释器)有一个全局解释器锁,一次只能执行一个线程。因此,您的测试在使用 MRI 时不会并行运行。

您可以使用支持并发线程(如 JRuby 或 Rubinius)的 Ruby 解释器让测试并行运行。

Read this article for more details.

【讨论】:

天哪...我绝对确定我读到 Minitest 使用 fork 进行并行测试。有什么方法可以让 Minitest 使用多处理而不是多线程进行并行测试? @Hubro 你可以尝试使用spork-minitest,见***.com/questions/9932384/spork-minitest【参考方案2】:

severin's answer关于由于 GIL 导致 MRI 无法并行执行是正确的。 (免责声明:我写了他链接到的文章。)在许多文章中,语言有点模糊,但您可以read this article 进行非常简单的描述。

如果您仍然对并行运行测试感兴趣并且无法更改 Ruby 解释器,请查看 parallel_tests gem 作为替代方法,尽管有一些限制。

【讨论】:

【参考方案3】:

要并行运行测试,您需要支持并行执行的 Ruby 版本(例如 JRuby),或者您可以使用简单的 shell 命令来启动多个 minitest 运行。

例如使用 gnu 并行:

find test -type f | parallel --dry-run  bundle exec rake test TEST=

dry-run 标志是为了让您在运行它之前可以看到正在发生的事情;如果您对命令会执行您想要的操作感到满意,请忽略 dry-run 标志。)

bundle exec 和 rake 的开销非常高。并行执行的核心优势是确保您的测试行为正确——即核心优势是而不是速度。如果您使用并行,您可能想尝试spork,它可以让预热的应用程序准备就绪。

【讨论】:

以上是关于为啥我的 Minitest 测试没有并行运行?的主要内容,如果未能解决你的问题,请参考以下文章

运行minitest时出错,期待但是渲染

在最新的VScode中运行Minitest - 显示Ansi颜色代码

带有 jruby rake 测试任务的 MiniTest falis

在 Rails 中,为啥我的邮件正文只在我的测试中是空的?

为啥我的自动化测试在一起运行时会失败,但单独通过?

有没有办法在本地机器上运行并行柏树测试,例如 5 个流