我最近发现我的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
答案 0 :(得分:5)
Minitest使用线程而非进程来进行并行测试。
由于MRI(标准Ruby解释器)具有全局解释器锁,因此一次只能执行一个线程。因此,在使用MRI时,您的测试不会并行运行。
通过使用支持JRuby或Rubinius等并发线程的Ruby解释器,您可以让测试并行运行。
答案 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
,以便为预热的应用做好准备。