为啥我的 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 测试没有并行运行?的主要内容,如果未能解决你的问题,请参考以下文章
在最新的VScode中运行Minitest - 显示Ansi颜色代码