为什么我的Minitest测试并行运行?

时间:2014-10-10 10:46:59

标签: ruby parallel-processing minitest

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

require "minitest/hell"

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

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

(byebug) Minitest::Test.test_order
:parallel

那是怎么回事?


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

$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    1
Core(s) per socket:    4
Socket(s):             2
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 62
Stepping:              4
CPU MHz:               2600.000
BogoMIPS:              5200.00
Hypervisor vendor:     VMware
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              20480K
NUMA node0 CPU(s):     0-7

3 个答案:

答案 0 :(得分:5)

Minitest使用线程而非进程来进行并行测试。

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

通过使用支持JRuby或Rubinius等并发线程的Ruby解释器,您可以让测试并行运行。

Read this article for more details.

答案 1 :(得分:3)

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

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

答案 2 :(得分:2)

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

例如,使用gnu parallel:

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

dry-run标志是这样你可以在运行之前看到发生了什么;当你满意命令会做你想做的事情时,省略dry-run标志。)

捆绑exec和rake的开销非常高。并行执行的核心优势是确保您的测试正常运行 - 即核心优势是而不是速度。如果您使用并行广告,则可能需要尝试spork,以便为预热的应用做好准备。