はじめに
deviseを使用したユーザー登録のテストコードを書いたので、備忘録として書き残します。
なお、内容はとても簡単な、初学者向けのものなります。
使用Gem等
- ruby, 2.5.1
- rails, ~> 5.2.3
- devise
- rspec-rails, ~>3.5
- factory_bot_rails
上記のGemをインストールします。
なお、web_console というgemはtest環境で動かすと不具合が起きる可能性があるgemなのでdevelopment環境でのみ動くようにします。
group :development do ~ endの記述が無ければ作成し、既にあればその記述の間にweb_consoleを移動させます。
Rspecの設定ファイルを作成
ターミナルで下記のコマンドを実行します。
rails g rspec:install
すると以下のファイルが作成されます。
create .rspec
create spec
create spec/spec_helper.rb
create spec/rails_helper.rb
rails_helper.rb
RailsにおいてRSpecを利用する際に、共通の設定を書いておくファイルです。各テスト用ファイルでこちらのファイルを読み込むことで、共通の設定や、メソッドを適用します。
spec_helper.rb
rails_helper.rbと同じくRSpec用の共通の設定を書いておくファイルですが、こちらはRSpecをRails無しで利用する際に利用します。
specファイル
RSpecによるテストコードが書かれたファイルのことを、specファイルと呼びます。全てのspecファイルは、先ほどのrails g rspec:installコマンドで生成された「specディレクトリ」の中に格納しておきます。
モデルに関するテスト用ファイルであればspec/models/以下に、コントローラーに関するテスト用ファイルであればspec/controllers/以下に格納されます。appディレクトリ以下にあるテストの対象となるコードの在り処と対応させます。
specファイルの命名規則
specファイルは対応するクラス名_spec.rbという名前になります。今回はまず「user.rb」に関するspecファイルを作成するので、その場合の名前は「user_spec.rb」になります。
.rspecに以下を記述
--format documentation
これで準備はrspecの準備は完了です。
factory_botの設定
ダミーのインスタンスを作成するために、factory_botを設定していきます。
FactoryBot.define do
factory :user do
name {"abe"}
email {"abe@gmail.com"}
password {"00000000"}
password_confirmation {"00000000"}
end
end
factory_bot
簡単にダミーのインスタンスを作成することができるGemです。他のファイルで予め各クラスのインスタンスに定めるプロパティを設定しておき、specファイルからメソッドを利用してその通りのインスタンスを作成します。factory_botを利用すれば、user_spec.rbは以下のように短い記述にすることができます。
user = User.new(name: "abe", email: "abe@gmail.com", password: "00000000", password_confirmation: "00000000")
# これがfactory_botを使用すると以下のようにできます
user = build(:user)
buildメソッド, createメソッド
buildメソッド、createメソッドはfactory_botにおける最も基本的なメソッドです。
buildメソッド
引数にシンボル型で取ったクラス名のインスタンスを、factory_botの記述をもとに作成します。
createメソッド
buildとほぼ同じ働きをしますが、createの場合はテスト用のDBに値が保存されます。
注意すべき点として、1回のテストが実行され、終了する毎にテスト用のDBの内容がロールバックされます。(保存された値がすべて消去されてしまう)
従って、binding.pry等でテストの実行を一時停止しないとテスト用のDBに保存された値を確認することはできません。
これで、factory_botの準備も整いました。
テストコードを書く
テストコードは以下のように書いていきます。
describe "hogehoge" do
it "1 + 1は2になること" do
expect(1 + 1).to eq 2
end
end
describe
1行目のdescribeは、直後のdo ~ endまでのテストのまとまりを作ります。describeの後に続く""の中にはそのまとまりの説明を書きます。
itとexample
2行目のitはexampleと呼ばれる実際に動作するテストコードのまとまりを表します。itの後に続く""の中にはそのexampleの説明を書きます。
エクスペクテーション
実際に評価される式のことです。it do ~ endの間に書きます。上記の式ではexpect(1 + 1).to eq 2の部分がエクスペクテーションです。
expect(X).to eq Y
エクスペクテーションの文法です。xの部分に入れた式の値がYの部分の値と等しければ、テストが成功します。eqの部分を、マッチャと言います。
マッチャ
エクスペクテーションの中で、テストが成功する条件を示します。例えばeqは「等しければ」という意味になります。他にも
include(含んでいれば)、valid(バリデーションされれば)など複数のマッチャが存在します。
実際に書いてみる
ユーザー登録時にnameがなければ登録ができないことをテストします。
そのため、factory_botで設定したダミーインスタンスを、nameをnilで作成します。
describe User do
describe '#create' do
it "nameがない場合は登録できないこと" do
# userインスタンスのnameをnilでbuildします
user = build(:user, name: nil)
# 作成したインスタンスがバリデーションによって保存ができない状態かチェックする
user.valid?
# エラー文が入った配列を取り出し、includeマッチャを利用してエクスペクテーションを作る
expect(user.errors[:nickname]).to include("can't be blank")
end
end
end
次に、テストを実行します。以下のコマンドをターミナルで実行します。
bundle exec rspec
以下のように表示されれば成功です。
User
#create
nameがない場合は登録できないこと
Finished in 0.53132 seconds (files took 3.64 seconds to load)
1 example, 0 failures
おわり
以上で簡単なテストを行うことが出来ました。
色々とまとまりのない記事になってしまったので、内容を分けて再度投稿するかもしれません。
最後まで読んでいただき、ありがとうございました。