Edited at

RailsアプリへのRspecとFactory_botの導入手順


はじめに

導入に手こずったので、RspecとFactory_botを導入する手順を記事に残そうと思います。基本的にはFactory_girlと同じ(だと思う....)


追記履歴

2018/02/02 supportディレクトリのパス修正

2018/04/17 bin/rspecの記載を追加

2019/03/05 タイポの修正


動作環境


  • macOS High Sierra


  • ruby, railsのバージョン


$ ruby -v

ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin17]

$ rails -v
Rails 5.1.4


導入手順


1. Gemのインストール

以下のようにGemfileにRails用のrspecとfactory_botのgemを加えて、インストールを行います。


Gemfile

group :development, :test do

gem 'rspec-rails'
gem "factory_bot_rails"
end


2. rspecの導入

まず、以下のコマンドでRailsアプリに、rspecを導入します。

$ bundle exec rails generate rspec:install

create .rspec
create spec
create spec/spec_helper.rb
create spec/rails_helper.rb


3. rspecの生成ファイルの定義

次にrails generate model等のgenerationコマンドで生成されるrspecファイルを設定していきます。設定ファイルはconfig/application.rbです。

以下が、設定例です。falseをつけると不要なテストファイルは作成されなくなります。

自分がRailsのテストを書く場合、基本的にrequest_spec, model_spec だけ書くので、それ以外はfalse を指定しています。これは現場のルールによって修正してください。


config/application.rb

config.generators do |g|

g.test_framework :rspec,
view_specs: false,
helper_specs: false,
controller_specs: false,
routing_specs: false
end


4. Factory_botの設定


spec/rails_helper.rb


RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods

end


上述のコードを加えることで、以下のようにrspecのテストコード中でFactory_botのメソッドを使用する際に、名前空間の指定を省略できるようになります。

 # 通常FactoryBotをつけないと、メソッドを呼べない

user = FactoryBot.create(:user)

# 上の設定を追加することで、FactoryBotの記述が省略できる。
user = create(:user)


5. rails_helper.rbの設定

次に、/spec/rails_helper.rb内で以下の一文がコメントアウトされているので、コメントアウトを外してください。これでspec/support/配下のファイルを読み込むことができます。


/spec/rails_helper.rb

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }


この設定は必須ではないですが、やっておいた方がいいと思います。理由としては、テスト用のヘルパーメソッドを使う際に記述するファイル置き場なので、利用用途が多いからです。

ここまでで、rspec, factory_botの設定は終了です。


使って見る


1.テストデータの定義

例えばUserモデルに関しては、テストデータの定義は/spec/factories/users.rbに行います。以下は定義例です。データを生成する毎に通し番号をふってユニークな値を作るようにしています。


/spec/factories/users.rb

FactoryBot.define do

factory :user do
sequence(:name) { |n| "TEST_NAME#{n}"}
sequence(:email) { |n| "TEST#{n}@example.com"}
end
end


2. Specテスト内でのテストデータの生成(Factory_botの使い方)

使い方としては、以下のようにcreateか、buildでモデルを作成して、テストデータとして使うのが基本だと思います。


# DBへレコード生成
@user = create(:user)

# モデルのみの作成
@user = build(:user)

以下に、Userモデルのバリデーションをチェックするテストを書きました。参考になればどうぞ。


/app/models/users.rb

class User < ApplicationRecord

validates :name, presence: true
validates :email, presence: true
end


/spec/models/users_spec.rb

require 'rails_helper'

RSpec.describe User, type: :model do
before do
@user = build(:user)
end

describe 'バリデーション' do
it 'nameとemailどちらも値が設定されていれば、OK' do
expect(@user.valid?).to eq(true)
end

it 'nameが空だとNG' do
@user.name = ''
expect(@user.valid?).to eq(false)
end

it 'emailが空だとNG' do
@user.email = ''
expect(@user.valid?).to eq(false)
end
end
end



3. Rspecテストの実行

作成したテストは以下のコマンドで実行できます。

$ bundle exec rspec spec/models/users_spec.rb

また、行数を指定することで、itdescribe単位でテストを実行でき、逆にディレクトリを指定することで配下も含めた対象ファイル全てを一度に実行できます。

# users_spec.rbの12行目にあるテストを実行

$ bundle exec rspec spec/models/users_spec.rb:12

# 全てのテストファイルを実行
$ bundle exec rspec spec


4. binstubでテスト実行


binstubの概要

rspecのテストの実行方法には上述の他に、binstubから使う方法もあります。

binstubからrspecを実行するとSpringの恩恵を得ることができ、実行開始時間を早めることができ便利です。

Spring


binstubの導入

ます、必要なGemをインストールします。Gemfileに以下のgemファイルを記述し、bundle installでインストールします。

group :development, :test do

gem 'spring-commands-rspec'

end

次に、以下のbundleコマンドを実行し、rspecのbinstubをインストールします。

$ bundle exec spring binstub rspec

これで準備完了です。


実行コマンド

$ bin/rspec spec/


5. 「bundle exec rspec」 と 「bin/rspec」の使い分け


立ち上がりの速いbin/rspec

1つのテストファイルを実行する場合は、断然bin/rspecの方が実行が速いです。

新規機能に対して、新しくテストファイルを作成している際は、何度もテスト実行を繰り返すので、立ち上がりが速いbin/rspecを多用しますね。


立ち上がり後の実行スピードの速いbundle exec rspec

一方で、新規機能追加等で、既存の全てのテストが落ちていないか確認する際は、bundle exec rspecの方が起動後の実行スピードが速いので効率的です。テスト項目が100を超える場合は、その効果をより実感できると思います。


参考文献

↓これを読めば、基礎から実践的なものまで、体系的に学ぶことができます

Everyday Rails - RSpecによるRailsテスト入門

テスト駆動開発の習得に向けた実践的アプローチ


参考ページ

factory_girlがfactory_botに名前変更!使用方法の解説など

Rails RSpecの基本 ~導入編~

Spring