こんにちは、かつコーチです。
RSpecの基本を覚えると、次に気になるのが「Minitestとは何が違うのか」という疑問です。
「RailsはデフォルトでMinitestなのに、現場ではRSpecをよく見る」という状況に、混乱した経験がある方も多いのではないでしょうか。
この記事では、Rubyの標準ライブラリであるMinitestと、独自のDSL(記法)を持つRSpecの構文を比較しながら、どちらを選ぶべきかの判断軸を整理します。
読み終える頃には、プロジェクトやチームの状況に応じて、自信を持ってテストツールを選べるようになります。
基本の書き方:構文を比較する
手順1:同じテストをMinitestとRSpecで書き比べる
まずは、同じCalculatorクラスに対するテストを、それぞれの書き方で見てみましょう。
対象のクラスは以下の通りです。
# lib/calculator.rb
class Calculator
def add(a, b)
a + b
end
end
Minitestの場合
Minitestは標準ライブラリのため、追加のgemインストールなしで使えます。
# test/calculator_test.rb
require "minitest/autorun"
require "calculator"
class CalculatorTest < Minitest::Test
def setup
@calculator = Calculator.new
end
def test_add
assert_equal 3, @calculator.add(1, 2)
end
end
class ... < Minitest::Testのようにクラス定義でテストをまとめ、test_から始まるメソッド名でテストケースを表します。
検証にはassert_equal(期待値, 実際の値)のような、assert系メソッドを使います。
RSpecの場合
# spec/calculator_spec.rb
require "calculator"
RSpec.describe Calculator do
describe "#add" do
it "2つの数値を足した結果を返す" do
calculator = Calculator.new
expect(calculator.add(1, 2)).to eq(3)
end
end
end
RSpecはdescribeとitによるDSL(独自の書き方)でテストを表現し、expect(値).to eq(期待値)という書き方で検証します。
手順2:構文の違いを表で比較する
同じ検証をするにも、書き方が大きく異なることが分かります。
| 比較項目 | Minitest | RSpec |
|---|---|---|
| 提供形態 | Ruby標準ライブラリ | 外部gem(別途インストール) |
| テストの書き方 | クラス定義(class ... < Minitest::Test) | DSL(describe / it) |
| 検証の書き方 | assert_equal(期待値, 実際の値) | expect(実際の値).to eq(期待値) |
| 前処理 | setupメソッド | beforeブロック |
| 学習コスト | 低い(普通のRubyクラスとして書ける) | やや高い(独自のDSLを覚える必要がある) |
| 実行速度 | 比較的高速 | Minitestよりやや遅い傾向 |
| モック・スタブ | 標準機能はシンプル | rspec-mocksが豊富で柔軟 |
| Railsとの関係 | rails newのデフォルト | Railsでも定番だが別途導入が必要 |
手順3:前処理(setup)の書き方の違いを見る
複数のテストで共通の準備をしたい場合の書き方も比較しておきましょう。
# Minitest
class CalculatorTest < Minitest::Test
def setup
@calculator = Calculator.new
end
def test_add
assert_equal 3, @calculator.add(1, 2)
end
end
# RSpec
RSpec.describe Calculator do
before do
@calculator = Calculator.new
end
it "2つの数値を足した結果を返す" do
expect(@calculator.add(1, 2)).to eq(3)
end
end
Minitestでは通常のRubyクラスと同じ感覚でsetupメソッドを定義するのに対し、RSpecではbeforeブロックという専用の記法を使います。
「普通のRubyのクラス・メソッドとして理解できるMinitest」と、「独自の言語のようなDSLを新しく覚えるRSpec」という違いが、このsetupとbeforeの比較によく表れています。
よくあるつまずきポイント・エラー対処
DSLの記法を混同してしまうミス
❌ Before:RSpecの構文でMinitestのファイルを書いてしまう
わたしが2つのツールを行き来していたとき、案件を切り替えるたびに構文を混同してしまうことがありました。
Minitestのファイルに、RSpecのdescribeとexpectを書いてしまった例です。
# test/calculator_test.rb(Minitestのはずが…)
require "minitest/autorun"
require "calculator"
describe Calculator do
it "2つの数値を足した結果を返す" do
calculator = Calculator.new
expect(calculator.add(1, 2)).to eq(3)
end
end
実行すると、以下のようなエラーが出ました。
NoMethodError: undefined method `describe' for main:Object
RSpecのgemを読み込んでいないため、describeというメソッド自体が存在しない状態でした。
✅ After:Minitestの構文に統一する
Minitestのファイルには、Minitestの構文で書く必要があります。
# test/calculator_test.rb
require "minitest/autorun"
require "calculator"
class CalculatorTest < Minitest::Test
def test_add
calculator = Calculator.new
assert_equal 3, calculator.add(1, 2)
end
end
このエラーを経験してから、「今書いているファイルはMinitestなのかRSpecなのか」を、ファイルの先頭にあるrequire文で必ず確認する習慣がつきました。
undefined method 'describe'やundefined method 'expect'が出たときは、対象ファイルに合ったrequireとツールが揃っているかを、まず確認してみてください。
どちらを選ぶべきかの判断軸
最後に、実際の選定で迷ったときの判断軸を整理しておきます。
- 標準ライブラリだけで完結させたい・学習コストを抑えたい場合:Minitestを選ぶ
- チームや案件で既にRSpecが採用されている・可読性の高いDSLを重視する場合:RSpecを選ぶ
- 既存プロジェクトに途中から参加する場合:既存の採用ツールに合わせるのが基本(自己判断で混在させない)
- 個人の新規プロジェクトで初めてテストを書く場合:まずはMinitestで「テストを書く習慣」自体に慣れ、必要に応じてRSpecへ移行する
どちらか一方が絶対的に優れているわけではなく、チームの慣習と学習コストのバランスで選ぶのが実践的な判断軸です。
まとめ
この記事のポイント
- MinitestはRuby標準ライブラリで、普通のクラス定義としてテストを書ける
- RSpecは外部gemで、
describe・itという独自のDSLを使う - 検証の書き方は、Minitestが
assert_equal、RSpecがexpect().to eq() - 構文を混同すると
NoMethodErrorになるため、ファイルごとのrequireを確認する習慣が重要 - 選定は「学習コストを抑えたいか」「チームの慣習に合わせるか」で判断する
次に読むべき記事
テストの基礎を押さえたら、次はよくあるRubyのエラーメッセージの読み方を扱った記事で、デバッグ力をさらに高めていきましょう。
タグ: Ruby, 中級者向け, テスト