株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。
DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら弊社HPからご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい
また、Railsエンジニアも募集しておりますので、興味がありましたら弊社HPからご連絡いただけますと幸いです。
前提
2017年10月にFactory GirlがFactory Botに名前変更になったり、rails-controller-testingが必要になったりとしたので、Rails5でのRsepcの導入方法をまとめておこうと思います。
Rspecの導入
必要なgemのインストール
Gemfileを以下のように記述しbundle installします。
group :development, :test do
gem 'rspec-rails'
gem 'factory_bot_rails'
gem 'rails-controller-testing'
end
rails-contorller-testing
rails-controller-testing はこれまで rspec-rails だけで使えていた assigns がRails5から、このgemをインストールしないと使えなくなりました。
factory_bot_rails
factory_bot_railsは以前はfactory_girl_railsでしたが、名前に問題?があったため変更になりました。
既存のプロジェクトfactory_girl_railsからfactory_bot_railsへ変更する際は、こちらの記事を参照ください。
rspecのインストール
rspecの必要ファイルをインストールするため、以下のコマンドを実行してください。
bundle exec rails generate rspec:install
以下の3つのファイルが作成されます。
.rspec
spec/spec_helper.rb
spec/rails_helper.rb
Factory Botの設定のために、spec/rails_helper.rbに以下を記述します。
RSpec.configure do |config|
# 色々な記述があるので、一番下に追記する
config.include FactoryBot::Syntax::Methods
end
rails g controller ~~~ などのコマンドでrspec用のテストファイルを作成するために、application.rbに以下の記述を書き加えましょう。
config.generators do |g|
# 色々な記述があるので、一番下に追記する
g.test_framework :rspec,
fixtures: true,
view_specs: false,
helper_specs: false,
routing_specs: false,
controller_specs: true,
request_specs: false
g.fixture_replacement :factory_bot, dir: "spec/factories"
end
これでRspecの導入の完了です。
出力結果のカスタマイズ
また、テストの実行結果を見やすくしたい方は.rspecをカスタマイズするといいでしょう。
デフォルトの出力では以下のようになっています。
# デフォルトの出力結果
.
Finished in 0.02768 seconds (files took 3.09 seconds to load)
1 example, 0 failures
.rspecの記述を以下のように変更して実行すると出力結果が見やすくなります。
--format documentation
# 変更後の出力結果
TweetsController
GET #index
render the :index template
Finished in 0.02567 seconds (files took 2.97 seconds to load)
1 example, 0 failures
どこのテストが成功したのかわかりやすくなりました。
他にも色々なカスタマイズがあるので、調べみると面白いかと思います。
実行して確認
簡易的なTwitterのようなアプリケーションを考えましょう
ツイート情報を管理するためのTweetモデルがあるとします。
Tweetモデルは以下のような構成になっています。
create_table "tweets", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.string "text"
t.string "title"
end
specディレクトリ 以下に models, controllersディレクトリ を作成します。
これは、モデルとコントローラーの実際のrspecのテストを記述するファイルが入るディレクトリになります。
加えて、specディレクトリ 以下にFactory Botための factoriesディレクトリ を作成しましょう。
まず、tweetモデルのためのfacotoryを作成するために、spec/factories/tweets.rbを作成しましょう。
また、spec/factories/tweets.rbを以下のように記述しましょう。
FactoryBot.define do
factory :tweet do
title 'ビール好き集まれ'
text '全国のビール好きのために、各国の様々なビールを集めました。'
end
end
これでtweetモデルのFactoryができました。
次に、コントローラーのテストをしましょう。
app/controllers/tweets_controller.rbは以下のようになっています。
class TweetsController < ApplicationController
def index
@tweets = Tweet.all
end
end
ではテストしてみましょう。
spec/controllers/tweets_controller_spec.rbを作成しましょう。
また、以下の記述をしましょう。
require 'rails_helper'
describe TweetsController, type: :controller do
describe 'GET #index' do
it "render the :index template" do
get :index
expect(response).to render_template :index
end
end
end
正常にテストが完了した場合は以下のようになります。
.
Finished in 0.03011 seconds (files took 2.76 seconds to load)
1 example, 0 failures
一番最初の . (ドット)は成功しているという意味になります。
テストが失敗している場合は F となります。
ここで注意しなければならないことは、以下の通りです。
(ここが意外とはまるところ)
-
require 'rails_helper'の記述を忘れないこと- 記述を忘れた場合
NameError: uninitialized constant TweetsControllerというエラーがでてくる
- 記述を忘れた場合
-
describe TweetsController, type: :controller doのTweetsControllerの部分はシングルクオート、ダブルクオードなどで囲まないこと- 囲った場合
@controller is nil: make sure you set it in your test's setup method.というエラーがでてくる
- 囲った場合
参考にした記事
Rails RSpecの基本 ~導入編~
spec/controllers エラー @controller is nil: make sure you set it in your test's setup method.
RSpec の Progress Bar をカスタマイズする