[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

```ruby
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

```html
<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関数を使うと重複を解消できる。
```ruby
  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
> * [letメソッドとFactory Girl - RSpec/Capybara入門 - Ruby on Rails with OIAX](http://www.oiax.jp/rails/rspec_capybara_primer/let_and_factory_girl.html)
上記も読まなきゃいけないな。
### RSpec のテストを自動生成しない
手動でテストを作成する場合。

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

> * [3.2最初のテスト](http://railstutorial-ja.herokuapp.com/chapters/static-pages#sec-first_tests)
### undefined local variable or method `root_path' for #<rspec::Core::ExampleGroup ...
チュートリアルの「[第5章 レイアウトを作成する](http://railstutorial-ja.herokuapp.com/chapters/filling-in-the-layout#top)」をすすめていると下記のようなエラーが出た。

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

こちらを参考にしたら、とりあえず動きました。
> * [ruby on rails - Rspec and named routes - Stack Overflow](http://stackoverflow.com/questions/9475857/rspec-and-named-routes)

% subl spec/spec_helper.rb

RSpec.configure do |config|
# ruby on rails – Rspec and named routes – Stack Overflow
config.include Rails.application.routes.url_helpers

### NoMethodError: undefined method `full_title' for #<rspec::Core::ExampleGroup
ディレクトリもなかったし、読み込んでいないようだったので下記を追記したら動きました。

% subl static_pages_spec.rb
“`

require 'support/utilities'