Rubyのテストフレームワーク:RSpecを活用して品質を守る

Rubyのテストフレームワーク:RSpecを活用して品質を守る

RSpecはRuby向けの強力なテストフレームワークです。テスト駆動開発(TDD)や振る舞い駆動開発(BDD)をサポートし、コードの品質を保つために広く利用されています。RSpecの使い方やベストプラクティスについて深掘りします。

RSpecとは何か

RSpecはRuby用のテストフレームワークで、振る舞い駆動開発(BDD)に基づいて設計されています。

RSpecのインストール

RSpecの利用を始めるには、gemをインストールします。

# Gemfile
gem 'rspec'

$ bundle install
$ rspec --init

RSpecの基本構文

RSpecのテストは「describe」「it」「expect」などの構文で記述します。

# spec/sample_spec.rb
RSpec.describe "Basic RSpec Test" do
  it "should add two numbers" do
    result = 1 + 1
    expect(result).to eq(2)
  end
end

describeとcontextの使い分け

describeはテスト対象、contextは条件ごとのグループ化に使用します。

RSpec.describe Array do
  describe "#push" do
    context "when adding elements" do
      it "increases the size" do
        array = []
        array.push(1)
        expect(array.size).to eq(1)
      end
    end
  end
end

beforeとafterのフック

テスト前後に共通の処理を実行するためにbefore/afterフックを使用します。

RSpec.describe "Before and After Hooks" do
  before do
    @array = []
  end

  it "adds an element" do
    @array.push(1)
    expect(@array.size).to eq(1)
  end

  after do
    @array.clear
  end
end

テスト対象のモックとスタブ

モックやスタブを使って依存関係をシミュレーションします。

RSpec.describe "Mocking Example" do
  it "mocks a method call" do
    user = double("User")
    allow(user).to receive(:name).and_return("Alice")

    expect(user.name).to eq("Alice")
  end
end

RSpecでエラーハンドリングをテストする

例外が発生することをテストします。

RSpec.describe "Error Handling" do
  it "raises an error" do
    expect { raise StandardError, "An error occurred" }.to raise_error(StandardError)
  end
end

RSpecのsubjectとlet

subjectやletを使ってテストコードを簡潔にします。

RSpec.describe Array do
  subject { [] }
  
  let(:element) { 1 }

  it "is empty initially" do
    expect(subject).to be_empty
  end

  it "adds elements" do
    subject.push(element)
    expect(subject.size).to eq(1)
  end
end

RSpecのshared_examples

共通のテストケースを再利用するにはshared_examplesを使用します。

RSpec.shared_examples "a collection" do
  it "responds to size" do
    expect(subject).to respond_to(:size)
  end
end

RSpec.describe Array do
  it_behaves_like "a collection"
end

RSpec.describe Hash do
  it_behaves_like "a collection"
end

RSpecのテスト出力をカスタマイズする

テスト結果の表示形式をカスタマイズします。

RSpec.configure do |config|
  config.formatter = :documentation
end

テストをフィルタリングして実行する

特定のテストのみを実行するためにタグを使用します。

RSpec.describe "Tagging Examples" do
  it "runs this test", :focus do
    expect(1 + 1).to eq(2)
  end

  it "skips this test" do
    expect(1 + 2).to eq(3)
  end
end
$ rspec --tag focus

RSpecの組み合わせテスト

複数の条件を組み合わせてテストします。

RSpec.describe "Combination Test" do
  [true, false].each do |condition|
    it "returns expected result when condition is #{condition}" do
      result = condition ? "yes" : "no"
      expect(result).to eq(condition ? "yes" : "no")
    end
  end
end

FactoryBotを使ってデータを簡単に生成する

RSpecではFactoryBotを使ってデータを効率的に生成します。

# Gemfile
gem 'factory_bot'

# spec/factories/user.rb
FactoryBot.define do
  factory :user do
    name { "John Doe" }
    age { 30 }
  end
end

# spec/models/user_spec.rb
RSpec.describe User do
  let(:user) { build(:user) }

  it "has a valid factory" do
    expect(user.name).to eq("John Doe")
    expect(user.age).to eq(30)
  end
end

まとめ

RSpecはテストの記述を柔軟かつシンプルにし、コード品質を向上させます。基本構文からフック、モック、タグ、FactoryBotまでを活用することで、効率的にテストを運用できます。