its

its は引数として与えたものに対してテストを行います:

require 'spec_helper'

describe User do

  before do
    @user = User.new(name: "おこ", email: "ocoao@example.com",
                     password: "ocoao", password_confirmation: "ocoao") }
  end

  subject { @user }

  describe "remember token" do
    before { @user.save }

    its(:remember_token) { should_not be_blank }
  end
end

以下と等価です:

it { @user.remember_token.should_not be_blank }

テストの書き方 (2)

以下の 3 つのテストをするコードです:

  • h1 タグ内に Sample App という文字が現れる.
  • title タグ内に full_title('') の戻り値の文字が現れる.
  • title タグ内に「|Home」という文字が現れない.
require 'spec_helper'

describe "StaticPages" do

  subject { page }

  describe "Home page" do
    before { visit root_path }

    it { should have_selector 'h1', text: 'Sample App' }
    it { should have_selector 'title', text: full_title('') }
    it { should_not have_selector 'title', text: '| Home' }
  end
end
  • root_patch が有効になるためには routes.rb で root to: 'static_pages#home' などとしてルートを通しておく必要があります.
  • full_title('') は spec/support/utilities.rb で定義しています.
    spec/support/utilities.rb で定義した関数は自動でテストコード内で使えるようになります.
subject { page }

という記述により,

it { page.should have_selector 'h1', text: 'Sample App' }

it { should have_selector 'h1', text: 'Sample App' }

と書くことができます.

テストの書き方 (1)

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

上のテストが通らない場合のエラーメッセージは下のようになります.
テストコードのダブルクォートで囲った部分の文言を工夫するとテスト結果がわかりやすくなります.

$ 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')
       expected there to be content "Sample App" in "SampleApp\n\nSampl App\n\n  This is the home page for the\n  Ruby on Rails Tutorial\n  sample application.\n\n\n"
     # ./spec/requests/static_pages_spec.rb:9:in `block (3 levels) in <top (required)>'

Finished in 0.46674 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/requests/static_pages_spec.rb:7 # StaticPages Home page should have the content 'Sample App'

Randomized with seed 60569

Capybara の機能

文字列が表示されているかどうかのテスト:

visit URL
page.should have_content('文字列')

visit URL は URL へのアクセスシミュレートです.

第一引数に指定した「タグ」が存在しその中身が「文字列」と一致するかのテスト:

visit URL
page.should have_selector('タグ', :text => '文字列')

BCrypt の cost factor をテスト環境向けに再定義

BCrypt アルゴリズムによるパスワード暗号化の処理にはかなりの時間がかかります. テスト環境用に BCrypt アルゴリズムのパスワード暗号化レベルを最小にすることで処理速度を早めます:

SampleApp::Application.configure do
  (省略)

  require 'bcrypt'
  silence_warnings do
    BCrypt::Engine::DEFAULT_COST = BCrypt::Engine::MIN_COST
  end
end

※ 小規模なテスト (39 examples) でも約 3 秒から半分の 1.5 秒前後になりました.

テスト生成

$ bundle exec rails g integration_test テスト名
      invoke  rspec
      create    spec/requests/テスト名_spec.rb

テスト実行

bundle exec rake
bundle exec rspec ファイル名(フォルダ名)
bundle exec rspec spec/requests/user_pages_spec.rb -e "signup with valid information after saving the user"

3つ目の記述で実行されるのは以下の部分:

describe "UserPages" do
  (省略)

  describe "signup" do
    (省略)

    describe "with valid information" do
      (省略)

      describe "after saving the user" do
        (ここが実行される)
      end
    end
  end
end

テスト用データベースの作成

bundle exec rake db:test:prepare