[Ruby on Rails 3, Ruby on Rails 4] RSpec/Capybara/FactoryGirl: FactoryGirl を使ったテストを試す

fixture を置き換えるツール。Rubyコードで定義する。

Contents

Gemfile

group :test do
  gem 'factory_girl_rails', '4.1.0'
end

ファクトリの定義

Userモデルオブジェクトをシミュレートするためのファクトリーを spec/factories.rb に置きます。
RSpecによって自動的に読み込まれます。
spec/factories ディレクトリ配下に定義する方法もあるよう。

% rails g factory_girl:model モデル名単数 属性名1:型 属性名2:型 ... 属性名n:型

spec/factories/モデル名複数.rb に雛形がつくられる。

spec/factories.rb

FactoryGirl.define do
  factory :user do
    name     "Michael Hartl"
    email    "michael@example.com"
    password "foobar"
    password_confirmation "foobar"
  end
end

テストコード

RSpec の letコマンドとFactoryGirlメソッドを使用してUserのファクトリーを作成することができます。

letでは値がメモ化 (memoize) されるという特長があり、ある呼び出しから次の呼び出しに渡って値を利用できます。
spec/requests/user_pages_spec.rb

require 'spec_helper'
describe "UserPages" do
  subject { page }
  describe "profile page" do
    let(:user) { FactoryGirl.create(:user) }
    before { visit user_path(user) }
    it { should have_selector('h1',    text: user.name) }
    it { should have_selector('title', text: user.name) }
  end
end

テストの高速化

BCryptのコストファクターをテスト環境向けに再定義することで、テストを高速化できる。

config/environments/test.rb

# Speed up tests by lowering BCrypt's cost function.
  require 'bcrypt'
  silence_warnings do
    BCrypt::Engine::DEFAULT_COST = BCrypt::Engine::MIN_COST
  end

テスト

定義前

% time bundle exec rspec spec/
.................................
Finished in 3.84 seconds
33 examples, 0 failures
Randomized with seed 28268
bundle exec rspec spec/  1.05s user 0.16s system 22% cpu 5.358 total

定義後

% time bundle exec rspec spec/
.................................
Finished in 0.92622 seconds
33 examples, 0 failures
Randomized with seed 43406
bundle exec rspec spec/  1.04s user 0.16s system 50% cpu 2.397 total

確かに速くなったようです。

補遺