Minitest / RSpec
Minitest ships with the Ruby standard library and is the default test framework for new Rails apps. It is small, fast, and offers both classic xUnit-style and spec-style DSLs in one library. Reach for RSpec only if you specifically want its matcher library or shared-example DSL.
Minitest unit, spec, mocks, and parallel runs
EXAMPLE
# test/test_helper.rb
require "minitest/autorun"
require "minitest/pride" # colourful dots; opt out in CI
# Run tests in parallel processes
Minitest.parallel_executor = Minitest::Parallel::Executor.new(4)
# ---- lib/calc.rb ----
class Calc
def add(a, b) = a + b
def div(a, b)
raise ArgumentError, "divide by zero" if b.zero?
a / b
end
end
# ---- test/calc_test.rb ----
require_relative "test_helper"
require_relative "../lib/calc"
# 1) Classic xUnit style — explicit method names, clearest stack traces
class CalcTest < Minitest::Test
def setup; @c = Calc.new end
def teardown; end
def test_add_returns_sum
assert_equal 5, @c.add(2, 3)
end
def test_div_by_zero_raises
err = assert_raises(ArgumentError) { @c.div(1, 0) }
assert_match(/divide by zero/, err.message)
end
def test_skip_on_windows
skip "wonky on Windows" if RUBY_PLATFORM =~ /mingw|mswin/
assert_equal 2, @c.div(10, 5)
end
end
# 2) Spec style — describe/it/expect-style, same engine underneath
describe Calc do
before { @c = Calc.new }
it "adds two numbers" do
_(@c.add(2, 2)).must_equal 4
end
it "raises on divide by zero" do
_ { @c.div(1, 0) }.must_raise ArgumentError
end
end
# 3) Mocks and stubs — built in
require "minitest/mock"
class MailerTest < Minitest::Test
def test_sends_welcome
smtp = Minitest::Mock.new
smtp.expect(:deliver, true, [String, "alice@example.com"])
User.new("Alice", "alice@example.com").welcome!(smtp)
smtp.verify
end
def test_stubs_time
Time.stub :now, Time.new(2026, 6, 11) do
assert_equal 2026, Time.now.year
end
end
end
# Run from CLI
# ruby -Ilib -Itest test/calc_test.rb # one file
# bundle exec rake test # via Rake
# bundle exec rails test # in Rails
Why it matters
Spec style is just sugar over the xUnit base — `_(value).must_equal x` desugars to `assert_equal x, value`. Pick one style per file and stick to it; mixing styles in the same suite is the easy way to confuse a future reader of the diff.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
require 'minitest/autorun'
class UserTest < Minitest::Test
def test_greet
assert_equal 'hi, Ada', User.new('Ada').greet
end
end
Try it Yourself »
Discussion
Loading…