Minitest on Rails.

Why Minitest

Cover Image for Why Minitest
Dwight Watson
Dwight Watson

For many Rails developers RSpec is the testing library. It’s the first gem installed on a new Rails app. It has been considered the de-facto for some time. However, it does seem like the pendulum is starting to swing the other way.

Minitest comes for free with Rails out of the box. Over the past few years there has been significant investment in improving the testing experience - from adding automatic parallel testing, browser testing with system tests, CI files by default to extending the CLI experience with it’s own test runner. If there was a Rails Way then Minitest seems more like it than ever.

Convention over configuration

We use a framework like Rails to get the boilerplate out of the way and get on with the things that matter. We choose to adopt the conventions and defaults to make our lives easier. Most don’t complain about using ActiveRecord (some loud exceptions there, though), ActionMailer and all the other basics. Why should the test runner be any different?

By choosing to continue with Minitest we get a test runner that just works and understands Rails. Rails includes many assertion helpers like assert_response and assert_mail_enqueued_with - simple code that’s clear and expressive to make simple tests easy.

Many of the big players use Minitest too - Basecamp and Hey obviously, but also GitHub and Shopify.

Up-to-date

Not really wanting to point fingers, but other test runners like RSpec still haven’t added support for parallel testing. Or as new framework additions like ActiveStorage have come along the porting of new matchers can fall behind.

By sticking to Minitest you get access to the latest testing features as soon as they are available in Rails. No need to wait for other dependencies to catch up or change how they work just to be compatible.

It’s just Ruby

Sure, expect(user.name).to eq “Dwight" does read as some nice English, but it’s a wordy and syntax-heavy way to go about it. assert_equal “Dwight”, user.name is nice, plain, simple Ruby. We strive for that clarity in our application code, so why not our tests?

Just being Ruby lets you get away with simple ideas like using arrays to test repeated data, which often feels wrong in other DSLs.

[6, 4, 2, 1].each do |integer|
  assert_equal 0, 12 % integer
end

Finally, it makes it more accessible to other developers who join your project. Even if they aren’t familiar with Minitest yet the tests written in Minitest are easy to understand and emulate. If Minitest continues to grow in popularity more developers will be happy to join your team knowing they will get to use it.

Conclusion

Minitest is worth considering seriously for your next Rails project. It’s ready to roll from day one (and will start running tests as soon as you push it to GitHub), will scale with your app as the test suite grows, keep your tests closer to your code instead of through DSL abstractions and help you adopt new Rails features as they become available. Anything else, YAGNI.