Testing is built into Ruby — Minitest comes with the standard library. Good tests give you confidence to refactor.
Your First Test
Ruby
# calculator.rb
class Calculator
def add(a, b)
a + b
end
def divide(a, b)
raise ArgumentError, "Cannot divide by zero" if b == 0
a.to_f / b
end
endRuby
# test_calculator.rb
require "minitest/autorun"
require_relative "calculator"
class CalculatorTest < Minitest::Test
def setup
@calc = Calculator.new
end
def test_add
assert_equal 5, @calc.add(2, 3)
assert_equal 0, @calc.add(-1, 1)
end
def test_divide
assert_equal 2.5, @calc.divide(5, 2)
end
def test_divide_by_zero
assert_raises(ArgumentError) { @calc.divide(1, 0) }
end
endRun: ruby test_calculator.rb
Common Assertions
Ruby
assert_equal expected, actual # ==
assert_nil value # value.nil?
assert_empty collection # collection.empty?
assert_includes collection, item # collection.include?(item)
assert_in_delta 3.14, calc.pi, 0.01 # approximate float comparison
assert_raises(SomeError) { ... } # block must raise the errorTest-Driven Development (TDD)
- Red — write a failing test
- Green — write the minimum code to pass
- Refactor — improve the code while tests stay green
Ruby
def test_fizzbuzz
assert_equal "FizzBuzz", fizzbuzz(15)
assert_equal "Fizz", fizzbuzz(3)
assert_equal "Buzz", fizzbuzz(5)
assert_equal "7", fizzbuzz(7)
end
def fizzbuzz(n)
return "FizzBuzz" if (n % 15).zero?
return "Fizz" if (n % 3).zero?
return "Buzz" if (n % 5).zero?
n.to_s
endTips
- Write tests before writing code (TDD).
- Keep tests fast — slow tests don't get run.
- One assertion per test method (ideally).
Next: metaprogramming.