Testing with Minitest

Reviewed & published by Brayan K

Minitest is Ruby's built-in testing framework that lets you verify your code automatically with concise assertions, so you catch bugs before your users do.

Part of the free Ruby course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

You'll write test classes and assertions, use setup, check for raised errors, and try the spec style.

What You'll Learn in This Lesson

1️⃣ Your First Test

A Minitest test is a class that inherits from Minitest::Test. Every method whose name starts with test_ is a test. Inside, call assertions like assert_equal(expected, actual) or assert(condition). The line require 'minitest/autorun' makes the file run its tests automatically.

2️⃣ More Assertions, setup & assert_raises

setup runs before every test_ method, giving each test fresh, isolated state. Beyond assert_equal there's assert_nil, assert_includes, and assert_raises, which passes only if the block raises the expected exception.

require 'minitest/autorun'

class Calculator
  def divide(a, b)
    raise ArgumentError, "cannot divide by zero" if b.zero?
    a / b
  end
end

class CalculatorTest < Minitest::Test
  def setup
    # Runs before EVERY test_ method — fresh state each time.
    @calc = Calculator.new
  end

  def test_divide
    assert_equal 4, @calc.divide(8, 2)
  end

  def test_divide_by_zero_raises
    # assert_raises checks that the block raises the given error.
    assert_raises(ArgumentError) { @calc.divide(1, 0) }
  end

  def test_nil_and_includes
    assert_nil [1, 2].find { |n| n > 9 }
    assert_includes [1, 2, 3], 2
  end
end

3️⃣ Spec Style & Minitest vs RSpec

Minitest also offers a spec style that reads like a sentence: describe groups tests, it defines one, and expectations use _(value).must_equal expected. It's a lighter alternative to RSpec's expect(...).to DSL, with no extra gem to install.

require 'minitest/autorun'

# Spec style reads like a sentence — describe/it instead of test_ methods.
describe "String" do
  it "knows its length" do
    _("hello".length).must_equal 5
  end

  it "can upcase" do
    _("ruby".upcase).must_equal "RUBY"
  end

  it "reverses" do
    _("abc".reverse).must_equal "cba"
  end
end

# Run it with:  ruby test_spec.rb

Your turn. Complete two assertions about strings so the suite passes. Fill in each ___.

require 'minitest/autorun'

# 🎯 YOUR TURN — replace each ___ then run with: ruby test_str.rb
class StringTest < Minitest::Test
  def test_upcase
    assert_equal "HELLO", "hello".___      # 👉 method that uppercases
  end

  def test_length
    assert_equal ___, "ruby".length        # 👉 how many letters in "ruby"?
  end
end

# ✅ Expected summary line:
#    2 runs, 2 assertions, 0 failures, 0 errors, 0 skips

Mini-Challenge: Test a Stack

Build a tiny Stack and write a Minitest suite for it with a setup, an equality assertion, and an assert_raises. This mirrors how you'd test a real class. Run with ruby test_stack.rb.

# 🎯 MINI-CHALLENGE: test a Stack class.
# Save as test_stack.rb and run with: ruby test_stack.rb
#
# 1. Define a small Stack with push, pop, and empty?.
# 2. Write a Minitest::Test with a setup that makes a fresh stack.
# 3. Test that a new stack is empty, that push then pop returns the
#    item, and that popping an empty stack raises an error.
#
# ✅ Expected summary line:
#    3 runs, 4 assertions, 0 failures, 0 errors, 0 skips

# your code here

Common Errors (and the fix)

Pro Tips

📋 Quick Reference — Minitest

ConceptRuby
Load + runrequire 'minitest/autorun'
Test class< Minitest::Test
A testdef test_thing
Equalityassert_equal exp, act
Raisesassert_raises(E) { }
Before eachdef setup

🎉 Lesson Complete!

Practice quiz

How is Minitest distributed?

  • a paid gem
  • part of Rails only
  • built into Ruby, no install needed
  • a separate download

Answer: built into Ruby, no install needed. Minitest ships with Ruby itself.

What does require 'minitest/autorun' do?

  • registers an at_exit hook that runs the tests automatically
  • installs Minitest
  • imports assertions only
  • starts a web server

Answer: registers an at_exit hook that runs the tests automatically. autorun runs all defined tests when the file finishes loading.

A classic-style test class inherits from:

  • Minitest::Spec
  • Test::Unit
  • RSpec::Test
  • Minitest::Test

Answer: Minitest::Test. xUnit-style tests subclass Minitest::Test.

Which method names are run as tests in a Minitest::Test class?

  • any method
  • methods starting with test_
  • methods ending in _test
  • methods named check

Answer: methods starting with test_. Only methods whose names start with test_ are run.

What is the correct argument order for assert_equal?

  • assert_equal expected, actual
  • assert_equal actual, expected
  • order does not matter
  • assert_equal value only

Answer: assert_equal expected, actual. assert_equal takes expected first, then actual.

When does plain assert(value) pass?

  • when value is nil
  • only when value is true
  • when value is truthy (not nil or false)
  • when value is zero

Answer: when value is truthy (not nil or false). assert passes for any truthy value.

Which assertion checks that a block raises an error?

  • assert_error
  • assert_raises
  • assert_throws
  • assert_fails

Answer: assert_raises. assert_raises(Error) { ... } passes when the block raises that error.

What does the setup method do?

  • runs once before all tests
  • runs after each test
  • configures the seed
  • runs before every test_ method for fresh state

Answer: runs before every test_ method for fresh state. setup runs before each test, giving isolated state.

In Minitest spec style, which pair defines a test group and a test?

  • context / specify
  • describe / it
  • suite / case
  • group / test

Answer: describe / it. Spec style uses describe to group and it to define a test.

Compared to RSpec, Minitest is generally:

  • larger with a big matcher DSL
  • browser-based
  • small, built-in, and dependency-free
  • only for Rails

Answer: small, built-in, and dependency-free. Minitest favours simplicity and ships with Ruby; RSpec is a larger external gem.

Continue this course

Frequently asked questions

What is Minitest and why is it popular?

Minitest is Ruby's lightweight testing framework, and it ships with Ruby itself — no gem to install. It's tiny, fast, and supports two styles: a classic xUnit style (classes that subclass Minitest::Test with test_ methods and assertions) and a spec style (describe/it blocks). Because it's built in and dependency-free, it's the default for many libraries and a great place to learn testing.

How does require 'minitest/autorun' work?

Adding require 'minitest/autorun' at the top of a test file registers an at_exit hook that runs all defined tests when the file finishes loading. That's why you can just execute ruby test_file.rb and see results — there's no separate test runner command needed. Each test_ method (or it block) is discovered and run automatically, in a randomized order controlled by the seed.

What's the difference between assert and assert_equal?

assert(value) passes when value is truthy (anything but nil or false) — use it for boolean conditions. assert_equal(expected, actual) passes when the two are equal, and prints a helpful diff when they aren't, so it's better for value comparisons. There are many specialized assertions too: assert_nil, assert_includes, assert_raises (for exceptions), and assert_in_delta for floats. Use the most specific one for the clearest failure messages.

How is Minitest different from RSpec?

Both are popular Ruby test frameworks. Minitest is small, built into Ruby, and uses plain assertions (or a light spec layer). RSpec is a larger external gem with an expressive expect(...).to matcher DSL, rich built-in matchers, and lots of conventions. Minitest favours simplicity and speed; RSpec favours readability and a big ecosystem. Many projects are happy with Minitest's spec style, which gives describe/it without the extra dependency.