Ruby
Rails
RSpec
Capybara
RubyOnRails

Ruby on Rails のテストフレームワーク RSpec 事始め

前提として、Ruby on Rails で Hello World が表示できていること。
Ruby on Rails を始める方法は Ruby on Rails 事始め に記載。

RSpec とは

RSpec とは Ruby on Rails のテストフレームワークである。
RSpec は Gem パッケージとして提供されている。

RSpec の公式サイトはこちら

RSpec の使い方

まずは RSpec の Gem パッケージをインストールする。
(インストールするバージョンは RSpec の公式サイトを元に適宜修正する)

Gemfile
・・・
group :development, :test do
  gem 'rspec-rails', '~> 3.6'
end
・・・
RSpecのGemパッケージインストール
$ bundler install

Gem パッケージがインストールされたら、次は Rails ソフトウェアに対して RSpec 用の初期ファイルをインストールする。

RSpecのインストール
$ rails generate rspec:install
Running via Spring preloader in process 9045
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb

RSpec の実行

インストールが完了した段階でテストは空だが RSpec が実行できるようになる。
bundle インストールしている場合は、bundle exec コマンドで実行できる。

RSpecの実行方法(全テストの実行:オプション無のデフォルト動作)
$ bundle exec rspec
RSpecのmaintain_test_schemaのマイグレーション
$ rails db:migrate RAILS_ENV=test

上記のようにオプションを指定せずに RSpec を実行すると全テストを実行する。
テストの数が少ない場合はテストを実行するためにかかる時間の問題はないが、
特定のテストのみ実行すればよい場合には -e STRING オプションを指定すれば任意のテストを実行できる。

-e オプションの STRING にはテスト中の describe で記述した名前を指定する。
describe の書き方は後述する。

テストの作り方

テストファイルの命名規則と記述ルール

テストファイルは Ruby で記載する。
RSpec は default で spec ディレクトリ配下のファイルを自動でテストファイルとして認識する。(ファイル名規則: spec/**/*_spec.rb

Spec ファイルについて詳細な情報はこちら

テストファイルは必ず require 'rails_helper' を含める必要がある。(RSpec3以降)

テストする対象

テストする対象は、モデル、コントローラ、ビュー、ルーティングがあげられる。
RSpec ドキュメントには次のテスト対象が記述されている。

  • Model specs
  • Controller specs
  • Request specs
  • Feature specs
    • テストは RSpec.feature メソッドを使って記述する
      • オプションとして :type => :feature を指定する
    • Feature テストとは高レベルのアプリケーションの挙動について行うテストのこと。
    • Feature テストはブラウザ操作(ボタンクリックや input ボックスへの入力)を行う。
      • ブラウザ操作を行うために capybara (Gem パッケージ)をインストールする必要がある。
      • capybara がインストールされていないと rspec 実行時にテストが pending される。
  • View specs
  • Helper specs
  • Mailer specs
  • Routing specs
  • Job specs
  • System specs

テストファイルに記述する内容

テストする対象が決まったら、テストする項目を記述していく。
このときのポイントとして、テストファイル内には 「<テストする対象>は<~>であることが正しい」といった言葉に置き換えて項目を列挙する。

例えば「User は name, emailAddress を所有していることが正である」場合、

spec/models/user_spec.rb
describe "User" do                    # User モデルについて記述(describe)する
  it "is valid with a name and email" # name と email を保持していることが正である
  it "is invalid without a name"      # name が無いと無効である
end

などと、テスト項目(it 以降に記述した内容)を記述していく。
(なお、未だテスト項目の名前のみでテスト自体は記述していない)

テスト項目には確認したいただ1つの内容を記述する。
また、describe と it の内容を繋げて読むと文章になるよう、it 文では動詞から始める。
(上記例では "User is valid with a name and email." が文章になる)

参考情報:https://leanpub.com/everydayrailsrspec-jp/read

feature テストについて

capybara を使ったテストを記述する場合の、ブラウザ操作項目を記述する。

尚、capybara の公式ドキュメントは Module: Capybara を参照。

  • visit
    • 指定した URL パスへ HTTP GET によるアクセスを行う。
    • HTTP 応答された HTML 内容は次に記述する page に保持される。
  • page
    • ブラウザが保持する DOM ツリーを保持するオブジェクト
    • ページ内に特定のメッセージが出力されることを確認するためには expect と have_text を組み合わせる
      • 例:expect(page).to have_text("User was successfully created.")

フォーム操作

  • fill_in
    • input ボックスにテキストを入力する
  • click_button
    • button をクリックする(submmitボタン等)

サンプルテスト

前提として、scaffold で User モデル(name, email属性を持つ)を作成しています。
scaffold を使ったモデルの作り方は別記事 Ruby on Rails での best_in_place 事始め を参照のこと。

spec/features/user_spec.rb
require "rails_helper"

RSpec.feature "user management", :type => :feature do
  scenario "End User creates a new user" do
    visit "/users/new"

    fill_in "user_name", :with => "test_name"
    fill_in "user_email", :with => "test@example.com"
    click_button "Create User"

    expect(page).to have_text("User was successfully created.")
  end
end

トラブルシュート

RSpec を使う上でエラーが発生した場合等のトラブルシュートを見つけ次第記述していく。(見つけ次第、適宜追記予定)

rspecコマンド実行時のfeatureテストにおけるエラー

capybara 不足によるエラー

capybara不足によるエラー
Pending: (Failures listed here are expected and do not affect your suite's status)

  1) user management End User creates a new user
     # Feature specs require the Capybara (http://github.com/jnicklas/capybara) gem, version 2.2.0 or later. We recommend version 2.4.0 or later to avoid some deprecation warnings and have support for `config.expose_dsl_globally = false`.
     # ./spec/features/user_spec.rb:4


Finished in 0.01628 seconds (files took 4.12 seconds to load)
1 example, 0 failures, 1 pending
  • 原因
    • capybaraがインストールされていない
  • 対策
    • Gemfile の test グループに capybara を記述して bundle install する
  • 方法
    1. Gemfile に capybara を記述(バージョンは適宜変更)
    2. bundle install コマンドを実行
Gemfile
group :test do
    ・・・
  gem 'capybara', '~> 2.8'
end

click_buttonのメソッド不足によるエラー

click_buttonのメソッド不足によるエラー
  1) user management End User creates a new user
     Failure/Error: click_button "Create User"

     NoMethodError:
       undefined method `normalize_params' for Rack::Utils:Module
     # ./spec/features/user_spec.rb:9:in `block (2 levels) in <top (required)>'