[Ruby on Rails 4] RSpec/Capybara: rspec テストを試してみる

「Ruby on Rails チュートリアル」をさわってみます。

インストール

プロジェクトの作成

$ cd rails_projects
$ rails new sample_app --skip-test-unit
$ cd sample_app

--skip-test-unit は、Test::Unitフレームワークと関連しているtestディレクトリを作成しないようにするオプション。

Gemfile

group :development, :test do
  gem 'sqlite3', '1.3.5'
  gem 'rspec-rails', '2.11.0'
end
group :test do
  gem 'capybara', '1.1.2'
end
group :production do
  gem 'pg', '0.12.2'
end

bundle

$ bundle update
$ bundle install --without production

–without productionオプションを追加することで、本番環境のgemのみインストールしないようにすることができます。注: このオプションは “remembered option” と呼ばれるもので、このオプションを一度実行するとコマンドに保存され、今後Bundlerを実行するときにオプションを追加する必要がなくなります。このため、今後は単にbundle installを実行するだけで、自動的に本番環境用gemをスキップできるようになります。

$ rails generate rspec:install

テスト

結合テスト(integration_test)の例。

テストの作成

% be rails generate integration_test static_pages
      invoke  rspec
      create    spec/requests/static_pages_spec.rb
% subl spec/requests/static_pages_spec.rb
require 'spec_helper'
describe "StaticPages" do
  describe "Home page" do
    it "should have the content 'Sample App' " do
      visit '/static_pages/home'
      page.should have_content('Sample App')
    end
  end
end

RSpec はダブルクォート (“) で囲まれた文字列を無視する。
Capybaraのvisit機能を使って、ブラウザでの/static_pages/homeURIへのアクセスをシミュレーションする。

テストの実行

赤い F が1つ。

% bundle exec rspec spec/requests/static_pages_spec.rb
F
Failures:
  1) StaticPages Home page should have the content 'Sample App'
     Failure/Error: page.should have_content('Sample App')

修正

% subl app/views/static_pages/home.html.erb
<h1>Sample App</h1>
<p>This is the home page for the
  <a href="http://railstutorial.jp/">Ruby on Rails Tutorial</a>
  sample application.
</p>

テストの再実行

% bundle exec rspec spec/requests/static_pages_spec.rb
.
Finished in 0.21874 seconds
1 examples, 0 failures

RSpecのlet関数を使うと重複を解消できる。

  let(:base_title) { "Ruby on Rails Tutorial Sample App" }
  describe "Home page" do
    it "should have the h1 'Sample App'" do
      visit '/static_pages/home'
      page.should have_selector('h1', :text => 'Sample App')
    end
    it "should have the title 'Home'" do
      visit '/static_pages/home'
      page.should have_selector('title', :text => "#{base_title} | Home")
    end
  end

補遺

let method

上記も読まなきゃいけないな。

RSpec のテストを自動生成しない

手動でテストを作成する場合。

$ rails generate controller StaticPages home help --no-test-framework

undefined local variable or method `root_path’ for #<rspec::Core::ExampleGroup …

チュートリアルの「第5章 レイアウトを作成する」をすすめていると下記のようなエラーが出た。

undefined local variable or method `root_path' for #<rspec::Core::ExampleGroup ...

こちらを参考にしたら、とりあえず動きました。

% subl spec/spec_helper.rb
  RSpec.configure do |config|
    # [ruby on rails - Rspec and named routes - Stack Overflow](http://stackoverflow.com/questions/9475857/rspec-and-named-routes)
    config.include Rails.application.routes.url_helpers

NoMethodError: undefined method `full_title’ for #<rspec::Core::ExampleGroup

ディレクトリもなかったし、読み込んでいないようだったので下記を追記したら動きました。

% subl static_pages_spec.rb
require 'support/utilities'