【问题标题】: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

【问题讨论】:

    标签: ruby parallel-processing minitest


    【解决方案1】:

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

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

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

    Read this article for more details.

    【讨论】:

    • 天哪...我绝对确定我读到 Minitest 使用 fork 进行并行测试。有什么方法可以让 Minitest 使用多处理而不是多线程进行并行测试?
    • @Hubro 你可以尝试使用spork-minitest,见stackoverflow.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,它可以让预热的应用程序准备就绪。

      【讨论】:

        猜你喜欢
        • 2014-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多