Writing a Basic Minitest Test
Fast recall
Quick revision
Core answer
test block, prepares the input, calls the public behaviour, and checks the result with a specific assertion. Model tests commonly inherit from ActiveSupport::TestCase; integration tests use ActionDispatch::IntegrationTest. Assertions normally put the expected value first, as in assert_equal 118, invoice.total, and each test must be independent.Whether you know Minitest is Ruby's default test lib (test_ methods, assert/assert_equal), bundled, fast.
Using RSpec-style expect in Minitest (use assert) — or not knowing Minitest is Ruby's default.
Minitest: Ruby's default test lib. class < Minitest::Test; def test_x; assert/assert_equal; end. Fast, bundled. Run: bin/rails test.
Interview-ready guide
Interview answer
Rails uses Minitest by default. A model or plain application test commonly inherits from ActiveSupport::TestCase, while an HTTP workflow inherits from ActionDispatch::IntegrationTest. The base class connects the test to the Rails environment and supplies helpers for that boundary.
Use a clearly named test block, arrange the smallest useful input, call the public behaviour, and assert its result. For equality, write the expected value first: assert_equal 118, Price.total(100, tax_rate: 0.18). The name and assertion should make the broken promise obvious in failure output.
Use assert_equal for an exact value, refute for a false condition, assert_nil for absence, and assert_raises for an expected failure. A specific assertion communicates more than assert result and usually produces a clearer diagnostic when the actual value differs.
Use setup for small state every test truly needs, but keep important boundary values beside the assertion. Rails isolates normal database changes, not every global, file, clock, job, or network effect. A good test stays deterministic, leaves no shared state, and passes alone as well as in the whole suite.
Writing a Basic Minitest Test
Direct Answer
A Rails Minitest test inherits from the appropriate Rails test class, defines a clearly named test block, prepares the input, calls the public behaviour, and checks the result with a specific assertion. Model tests commonly inherit from ActiveSupport::TestCase; integration tests use ActionDispatch::IntegrationTest. Assertions normally put the expected value first, as in assert_equal 118, invoice.total, and each test must be independent.
Deep Dive & Architecture
Rails selects test helpers through inheritance. ActiveSupport::TestCase is suitable for models and plain application objects that need Rails support. ActionDispatch::IntegrationTest adds HTTP request methods and response access. System tests add a browser driver. Choosing the smallest boundary keeps setup and failure output focused.
Assertions are executable claims. assert_equal compares values, assert_includes checks membership, and assert_changes can verify a Rails state transition around a block. A generic assert result may pass for the wrong truthy value, so use an assertion that names the real promise whenever one exists.
Rails maintains a separate test database and normally isolates database changes between tests. That does not automatically isolate global variables, files, network services, clocks, or jobs. Those boundaries still need controlled data, fakes, or cleanup suited to the behaviour.
Test code is production support code: duplication can be extracted, but clarity comes first. A small local setup that exposes the scenario is often better than an abstract helper with several flags. When a failure occurs, the test name, input, assertion, and message should reveal what contract was broken.
Code Example
require 'minitest/autorun'
class Price
def self.total(subtotal, tax_rate:)
subtotal + (subtotal * tax_rate)
end
end
class PriceTest < Minitest::Test
def test_total_applies_the_tax_rate
assert_equal 118, Price.total(100, tax_rate: 0.18)
end
end
Common Mistakes & Pitfalls
Using RSpec-style expect in Minitest (use assert) — or not knowing Minitest is Ruby's default.
Check your understanding
Answer these without looking back at the article.
- When should a Rails test inherit from `ActionDispatch::IntegrationTest`?
- Why is `assert_equal expected, actual` better than a broad truthy assertion?
- What state can still leak even when database tests use transactions?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.