polishing ruby by ryan davis

Minitest Parallelization and You

Published 2012-12-12 @ 00:00

Tagged minitest

As announced at RubyConf 2012, minitest 4.2.0 was released with parallelization added. As I said then, I don’t care in the slightest about trying to make your tests run faster. You deserve your pain if you write slow tests. What I do care about greatly is making your tests hurt and this will do that.

Minitest added randomization back in 2008 (afaik, before anyone else, it even took rspec 4 years to follow suit) as an easy means of ensuring your tests were actually independent of each other. Parallelization will take that a step further and make sure you don’t have any dependencies across test suites.

So, how do you use it? Parallelization is opt-in only but very easy to do:

1
2
3
4
5
6
7
8
9
10
11
class TestMyPain < Minitest::Unit::TestCase
  parallelize_me!

  # ...
end

describe MyPain do
  parallelize_me!

  # ...
end

All parallelize_me! does is override test_order to return :parallel. The runner will take care of the rest. All parallel suites will be run in parallel. Remaining serial suites will be run after.

If you want to try it out globally, you can shortcut via:

1
require "minitest/hell"

It changes the default order from :random to :parallel. Expect stuff to break, it is named appropriately.

What Should You Make Parallel?

Ideally, everything… But that’s not terribly realistic. Some things are just better left serialized. For example, testing $stdout, $stderr, and $stdin because they’re global, they’re perfectly happy to print whatever you want whenever you want, but capture_io and assert_output won’t work right. You should move those tests to a serial suite so everything else can run parallel.

Try it out. Have fun. Find and fix bugs. Enjoy.