RailsのテストフレームワークRSpecの基礎知識

2014年7月8日(火)
黒田 努
実践Ruby on Rails 4 現場のプロから学ぶ本格Webプログラミング
顧客管理システムの構築を体験しながら、Railsアプリケーション開発のノウハウを習得!Amazon詳細ページへ
この記事は、書籍『実践Ruby on Rails 4 現場のプロから学ぶ本格Webプログラミング』の内容を、Think IT向けに特別にオンラインで公開しているものです。詳しくは記事末尾の書籍紹介欄をご覧ください。

RSpecの基礎知識

本記事では、テストフレームワークとしてRSpecを採用します。RSpecをうまく活用すると、簡潔で読みやすいテストコードを書くことができ、Railsアプリケーションの保守性を高めることができます。

しかし、RSpecの用語法や表記法はやや独特で、慣れるまでには時間がかかります。読者の中にはとまどいを覚える方がいらっしゃるかもしれませんが、次章以降を読み進めるうえでの鍵となりますので、是非じっくりと読んで理解してください。

テストとは

Webアプリケーション開発の文脈において、テストという言葉はさまざまな意味で用いられます。日常的な場面では、人がWebアプリケーションの動きを目視でチェックする作業を意味します。たとえば、Webアプリケーションをサーバーコンピュータにインストールし、人が実際にWebブラウザを操作して、仕様どおりの反応を返すかどうか確かめるといった作業です。

しかし、プログラマの間では「テスト」という言葉がしばしば異なる意味で用いられます。私たちは、専用のプログラムによってWebアプリケーションの動作を確認することを「テスト」と呼びます。この意味でのテストは自動で行われます。人間がディスプレイを見守っていなくてもテストが進行し、テストが終わると成功あるいは失敗という結果がディスプレイに表示されます。

本書では「テスト」という言葉を、ソフトウェアによって自動で実施されるテストという意味で用います。

テストを実行するための専用のプログラムを「テスト」と呼ぶ用法もあります。たとえば、私たちはしばしば「テストを書く」という言い方をします。これは、テストを実行するためのプログラムを作ることを意味します。

RSpecとは

前著『改訂新版 基礎Ruby on Rails』では、Railsに標準で組み込まれているテストフレームワークTest::Unitを用いたテストについて解説しましたが、本書ではRSpec(アールスペック)という別のテストフレームワークを採用することにします。

Rails 4では標準のテストフレームワークがTest::UnitからMiniTestに変更されました。MiniTestはTest::Unitの機能強化版で、Test::Unitとの互換性をほぼ保っています。

RSpecを採用した理由は、正直に言えば「私が普段使っているから」ということになります。RSpecはRailsプログラマの間で高い人気を獲得していますが、その独特の用語法や書き方になじめない方も多いようです。私はRSpecにはTest::Unitやその後継のMiniTestにはない優れた特徴があると考えています。

しかし、RSpecがRailsに組み込まれていないことからもわかるように、けっして「事実上の標準(de facto standard)」の地位をRails業界において確立しているわけではありません。

RSpecの初期設定

RailsでRSpecを利用する場合、一度だけ次のコマンドを実行する必要があります。

$ bin/rails g rspec:install

ゲストOSで実行してください。すると、specディレクトリが作られて、その下にspec_helper.rbというファイルが生成されます。初期状態での内容は次のとおりです(コメント行を省略しています)。

spec/spec_helper.rb

ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'

Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)

RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.order = "random"
end

Rails 4.1に対応するため、このファイルの7行目を次のように書き換えてください。

ActiveRecord::Migration.maintain_test_schema!

RSpec ―― はじめの一歩

RSpecがどんなものであるかを感覚的に理解するため、実際にRSpecによる簡単なテストコードを書いて、実行してみることにしましょう。

Baukisのプロジェクトディレクトリ直下にspecディレクトリがあります。その下にexperimentsというサブディレクトリを作り、string_spec.rbというファイルを作成してください。

spec/experiments/string_spec.rb

require 'spec_helper'

describe String do
  describe '#<<' do
    example '文字の追加' do
      s = "ABC"
      s << "D"
      expect(s.size).to eq(4)
    end
  end
end

RSpecのテストコードは、通常specディレクトリの下に置きます。ファイル名の末尾は_spec.rbで終わるようにしてください。これらのファイルをspecファイルと呼びます。

specファイルはspecディレクトリのサブディレクトリに適宜分類して配置します。どのサブディレクトリにどんなspecファイルを置くかは慣習的に決まっています。たとえば、モデルクラスに関するspecファイルはspec/modelsディレクトリに、APIに関するspecファイルはspec/requestsディレクトリに置くのが一般的です。しかし、独自のサブディレクトリを用意しても構いません。ここでは、RubyもしくはRailsの仕様に関する実験を行うspecファイルを置く場所としてexperimentsサブディレクトリを作成しました。これは本書独自のルールです。

テストコードの本体は次の3行です。

s = "ABC"
s << "D"
expect(s.size).to eq(4)

まず変数sに"ABC"という文字列をセットし、それに"D"という文字を追加しています。最後に、expectメソッドで変数sの状態を調べています。expectメソッドの使い方は後述しますが、ここではsの長さが4であるかどうかをチェックしています。

では、このspecファイルを実行してみましょう。ゲストOSのターミナルで、次のコマンドを実行してください。

$ bin/rspec spec/experiments/string_spec.rb

すると、次のような結果がターミナルに表示されます。

.

Finished in 0.13482 seconds
1 example, 0 failures

Randomized with seed 15657

ただし、3行目の「0.13482」および6行目の「15657」は、実行するたびに値が変化します。この結果の読み方については、後述します。

bin/rspecコマンドの結果の最終行に出力される「Randomized with seed ...」という行は、RSpecが内部的に利用している乱数のシード値(疑似乱数を計算するための係数)を表しています。RSpecは複数のエグザンプルをランダムな順番で実行するために乱数を利用しています。これ以降、テストの結果を掲載する際にはこの行を省略します。

このようにbin/rspecコマンドはspecファイルのパスを指定して個別に実行することも可能ですが、specファイルを含むディレクトリを指定して、そこに含まれるspecファイルを一括して実行することもできます。たとえば、次のコマンドはspecディレクトリ以下にあるすべてのspecファイルを実行します。

$ bin/rspec spec
株式会社オイアクス

東京大学教養学部卒。同大学院総合文化研究科博士課程満期退学。ギリシャ近現代史専攻。専門調査員として、在ギリシャ日本国大使館に3年間勤務。中学生の頃に出会ったコンピュータの誘惑に負け、IT業界に転身。株式会社ザッパラス技術部長、株式会社イオレ取締役を経て、技術コンサルティングとIT教育を事業の主軸とする株式会社オイアクスを設立。現在、同社代表取締役社長。また、2011年末にRuby on Rails によるウェブサービス開発専業の株式会社ルビキタスを知人と共同で設立し同社代表に就任(オイアクス社長と兼任)。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています