我刚刚发现我的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 回答
Minitest使用线程而不是进程来进行并行测试 .
由于MRI(标准Ruby解释器)具有全局解释器锁,因此一次只能执行一个线程 . 因此,使用MRI时,您的测试不会并行运行 .
通过使用支持JRuby或Rubinius等并发线程的Ruby解释器,您可以让测试并行运行 .
Read this article for more details.
由于GIL是正确的,因此MRI无法并行执行 . (免责声明:我写了他链接的文章 . )语言在许多写作中有点模糊,但你可以read this article进行非常简单的描述 .
如果您更改Ruby解释器,请查看parallel_tests gem作为替代方法,尽管有一些限制 .
要并行运行测试,您需要一个支持并行执行的Ruby版本(例如JRuby),或者您可以使用简单的shell命令来启动多个minitest运行 .
例如,使用gnu parallel:
(
dry-run
标志是这样你可以在运行它之前看到发生了什么;当你满意命令会做你想做的事情时,省略dry-run
标志 . )捆绑exec和rake的开销非常高 . 并行执行的核心优势是确保您的测试正常运行 - 即核心优势不是速度 . 如果您使用并行,您可能需要尝试
spork
,它可以保持预热的应用程序准备就绪 .