投稿機能テスト
モデルのテストのステップ
モデルのテストを完成させるためのステップは以下の通り。
1. テストで使うgemの導入
まずは、テストで使用するGemをアプリケーションに導入する。
問題1:テストで使うgemを導入する
ヒント:カリキュラムをさかのぼったり、自身で調べて導入まで行う
ヒント:ダミーデータの生成や、ファクトリを生成するなどテストを効率的に行うためのgemも併せて導入する
問題2:導入したgemをインストールする
ヒント:問題1でbundle installしたテスト用のgemを使用するためには、ターミナル上であるコマンドを実行する必要がある
1 2 3 4 5 6 7 8 |
1 2 3 4 |
# チャットスペースのディレクトリに移動
$ cd chat-space
# bundle install
$ bundle install
|
解説
まずはRSpecを利用するためのrspec-rails
、そして簡単にダミーのインスタンスを作成することができるfactory_bot_rails
、ダミーデータを作成するためのfaker
、コントローラのテストに必要なrails-controller-testing
の4つのGemをインストール。
テスト環境で使用するのでgroupはtestの場所に記入する。
その後、bundle installを実行。
1 |
1 2 |
# 下記の記述を追加
--format documentation
|
解説
ターミナルで上記のコマンドを入力するとrspecがインストールされる。
下記のファイルが作成されれば成功。
最後に、作成された「.rspec」ファイルを開き、--format documentation
の記述を行う。これで、テストの結果が見やすくなる。
RSpecでテストを行う
実際にテストを行っていく。
今回は、以下の項目をテストしていく。
モデルのテストが終わったら次のコントローラのテストに進む。
- メッセージを保存できる場合
- メッセージがあれば保存できる
- 画像があれば保存できる
- メッセージと画像があれば保存できる
- メッセージを保存できない場合
- メッセージも画像も無いと保存できない
- group_idが無いと保存できない
- user_idが無いと保存できない
問題3:FactoryBotを使用する準備をする
ヒント:テストで使用するデータをFactoryBotを用いて定義
ヒント:FactoryBotはある設定を行うことで記述を省略することができる
(模範解答で使用した画像のファイル名:test_image.jpg)
1 2 3 4 5 |
FactoryBot.define do
factory :group do
name {Faker::Team.name}
end
end
|
1 2 3 4 5 6 7 8 9 |
FactoryBot.define do
factory :user do
password = Faker::Internet.password(min_length: 8)
name {Faker::Name.last_name}
email {Faker::Internet.free_email}
password {password}
password_confirmation {password}
end
end
|
1 2 3 4 5 6 7 8 |
FactoryBot.define do
factory :message do
content {Faker::Lorem.sentence}
image {File.open("#{Rails.root}/public/images/test_image.jpg")}
user
group
end
end
|
1 2 3 4 5 |
#〜省略〜
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
#〜省略〜
end
|
解説
FactoryBotのデータの定義
FactoryBot
とfaker
を組み合わせることによって、テストで使用するデータを簡単に定義できる。
FactoryBot
の記法を省略するために、rails_helper.rb
に以下の記述を加える。
1 2 3 4 5 |
#〜省略〜
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
#〜省略〜
end
|
これで、rspecでFactoryBotを使用する準備ができた。
また、画像データについてはFakerで生成しない。
テスト用の画像を用意し、/public/images/の中に配置する。
ダミー画像の準備
1. publicディレクトリの中にimagesディレクトリを作成する
まずはご自身のchat-spaceのpublicディレクトリにimagesというディレクトリを作成する。
2. 適当な画像の名前をtest_image.jpg
に変更する
imagesディレクトリが作成できたら、次にMacに適当な画像を用意。
この画像をダミー画像として用いる。
適当な画像が用意できたら、それをtest_image.jpg
に名前を変更する。
3. 名前変更したtest_image.jpgをpublic/images
に配置する
用意したtest_image.jpgをpublic/imagesに配置できたら、ダミー画像の用意は完了。
このダミー画像はこの後のモデルのテストで用いるので、用意ができたらそのままで大丈夫。
手順の解説
今回の目的は、先ほど用意したダミー画像をrspecのテストで用いる画像として指定すること。
1 2 3 4 5 6 7 8 |
FactoryBot.define do
factory :message do
content {Faker::Lorem.sentence}
image {File.open("#{Rails.root}/public/images/test_image.jpg")}
user
group
end
end
|
上記のコードの以下の部分にパスを設定している。
1 |
image {File.open("#{Rails.root}/public/images/test_image.jpg")}
|
こちらは~/アプリケーション名/public/images.test_image.jpg
の画像をテストで用いるという意味。
Rails.rootの意味は/Users/~~/アプリケーション
までのパスを取得している。
詳しくはrails cをすれば確認できる。
画像は文字列をファクトリに記述するのではなく、画像を用意して、その画像を用いてファクトリに値を用意する必要がある。
「rspec carrierwave」といった言葉で調べてみる。
問題4:messageモデルのテストを行う
ヒント:保存できる場合、保存できない場合を条件にテストをグループ分けする
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
require 'rails_helper'
RSpec.describe Message, type: :model do
describe '#create' do
context 'can save' do
it 'is valid with content' do
expect(build(:message, image: nil)).to be_valid
end
it 'is valid with image' do
expect(build(:message, content: nil)).to be_valid
end
it 'is valid with content and image' do
expect(build(:message)).to be_valid
end
end
context 'can not save' do
it 'is invalid without content and image' do
message = build(:message, content: nil, image: nil)
message.valid?
expect(message.errors[:content]).to include("を入力してください")
end
it 'is invalid without group_id' do
message = build(:message, group_id: nil)
message.valid?
expect(message.errors[:group]).to include("を入力してください")
end
it 'is invaid without user_id' do
message = build(:message, user_id: nil)
message.valid?
expect(message.errors[:user]).to include("を入力してください")
end
end
end
end
|
解説
モデルでテストすべきは以下の点。
- メッセージを保存できる場合
- メッセージがあれば保存できる
- 画像があれば保存できる
- メッセージと画像があれば保存できる
- メッセージを保存できない場合
- メッセージも画像も無いと保存できない
- group_idが無いと保存できない
- user_idが無いと保存できない
今回の場合、テストのケースがメッセージを保存できる場合、メッセージを保存できない場合で分かれている。
このように、特定の条件でテストをグループ分けしたい場合、context
を使うことができる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
context
を使用することによって、テストが条件毎にまとまって読みやすくなるので、積極的に活用するとよい。
メッセージを保存できる場合のテスト
メッセージがあれば保存できる
既にファクトリーの定義が完了しているため、build(:message)
でMessageモデルのインスタンスを生成することができる。
1 2 3 |
it 'is valid with content' do
expect(build(:message)).to be_valid
end
|
build
メソッドは、カラム名: 値
の形で引数を渡すことによって、ファクトリーで定義されたデフォルトの値を上書きすることができる。今回は、メッセージがあれば保存できることを確かめたいので、image: nil
を引数として、画像を持っていないインスタンスを生成する。
1 2 3 |
it 'is valid with content' do
expect(build(:message, image: nil)).to be_valid
end
|
画像があれば保存できる
1 2 3 |
it 'is valid with image' do
expect(build(:message, content: nil)).to be_valid
end
|
同様に、画像があれば保存できる場合についても、content: nil
をbuildメソッドの引数とすることによって、メッセージを持っていないインスタンスを生成することができる。
メッセージと画像があれば保存できる
1 2 3 |
it 'is valid with content and image' do
expect(build(:message)).to be_valid
end
|
メッセージと画像があれば保存できる場合は、ファクトリーでデフォルトの値が定義されているので、build(:message)
と記述するだけで、メッセージと画像を持ったインスタンスを生成できる。
メッセージを保存できない場合のテスト
メッセージも画像も無いと保存できない
メッセージも画像もないと保存できない場合については、build
メソッドの引数でメッセージも画像もnilにすることによって、必要なインスタンスを生成することができる。
1 2 3 |
作成したインスタンスがバリデーションによって保存ができない状態かチェックするため、valid?
メソッドを利用する。
1 2 3 4 |
valid?
メソッドを利用したインスタンスに対して、errors
メソッドを使用することによって、バリデーションにより保存ができない状態である場合なぜできないのかを確認することができる。
contentもimageもnilの今回の場合、'を入力してください'というエラーメッセージが含まれることが分かっているため、include
マッチャを用いて以下のようにテストを記述することができる。
今回はエラー文を日本語化しているため、エラーメッセージも日本語のものでテストする。他国語や文言が違う場合は、実際にエラーメッセージとして扱われる文言に変更する必要がある。
1 2 3 4 5 |
expectの引数に関して、message.errors[:カラム名]
と記述することによって、そのカラムが原因のエラー文が入った配列を取り出すことができる。こちらに対して、include
マッチャを利用してエクスペクテーションを作っている。
user_idが無いと保存できない かつ group_idが無いと保存できない
最後に、group_idが無いと保存できない場合、user_idが無いと保存できない場合に関してだが、これらもメッセージも画像もないと保存できない場合と同じ方法でテストを書くことができる。
1 2 3 4 5 6 7 8 9 10 11 |
テストの実行結果
各テストコードの記述が終わったら、テストを実行。
1 |
$ bundle exec rspec spec/models/message_spec.rb
|
以下のような結果になれば成功。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ bundle exec rspec spec/models/message_spec.rb
Message
#create
can save
is valid with content
is valid with image
is valid with content and image
can not save
is invalid without content and image
is invalid without group_id
is invaid without user_id
Finished in 0.53507 seconds (files took 4.17 seconds to load)
6 examples, 0 failures
|
コントローラのテストのステップ
コントローラのテストを完成させるためのステップは以下の通り。
- deviseをテストで使用するための設定
- RSpecでテストを行う
1. deviseをテストで使用するための設定
コントローラでは、ログインしている場合としていない場合で動作が異なる。
ログイン状態とログインしていない状態を分けてテストできるように設定する。
ログインをしている、していないということはgemのdeviseに任せているので、deviseのテストについて調べる必要がある。
問題5:deviseをrspecで使用できるようにする
1 2 3 4 5 6 |
module ControllerMacros
def login(user)
@request.env["devise.mapping"] = Devise.mappings[:user]
sign_in user
end
end
|
1 2 3 4 5 6 |
解説
まず、/spec/support
ディレクトリに、controller_macros.rb
を作成し、
loginメソッドを定義する。
1 2 3 4 5 6 |
module ControllerMacros
def login(user)
@request.env["devise.mapping"] = Devise.mappings[:user]
sign_in user
end
end
|
その後、rails_helper.rb
に、deviseのコントローラのテスト用のモジュールと、先ほど定義したControllerMacrosを読み込む記述を行う。
1 2 3 4 5 6 |
これで、deviseをrspecで使用する準備ができた。
模範回答の通りに記述を行なってもエラーになる場合、下記設定を確認する。
rails_helper内のDir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
の記述のコメントアウトを外す。
1 2 3 4 5 |
2. RSpecでテストを行う
今回は、以下の項目をテストしていく。
メッセージ一覧ページを表示するアクション
- ログインしている場合
- アクション内で定義しているインスタンス変数があるか
- 該当するビューが描画されているか
- ログインしていない場合
- 意図したビューにリダイレクトできているか
問題6:messagesコントローラでメッセージ一覧を表示するアクションのテストを行う
ヒント:モデルのテストと同様に、今回も条件でテストを場合分けしてみる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
require 'rails_helper'
describe MessagesController do
let(:group) { create(:group) }
let(:user) { create(:user) }
describe '#index' do
context 'log in' do
before do
login user
get :index, params: { group_id: group.id }
end
it 'assigns @message' do
expect(assigns(:message)).to be_a_new(Message)
end
it 'assigns @group' do
expect(assigns(:group)).to eq group
end
it 'renders index' do
expect(response).to render_template :index
end
end
context 'not log in' do
before do
get :index, params: { group_id: group.id }
end
it 'redirects to new_user_session_path' do
expect(response).to redirect_to(new_user_session_path)
end
end
end
end
|
解説
メッセージ一覧を表示するアクションでテストすべきは以下の点。
- ログインしている場合
- アクション内で定義しているインスタンス変数があるか
- 該当するビューが描画されているか
- ログインしていない場合
- 意図したビューにリダイレクトできているか
今回はログインをしているかどうかを条件に、context
を用いてテストをグループ分けしてみる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
require 'rails_helper'
describe MessagesController do
describe '#index' do
context 'log in' do
# この中にログインしている場合のテストを記述
end
context 'not log in' do
# この中にログインしていない場合のテストを記述
end
end
|
続いて、今回のテストで必要なインスタンスを生成する記述を行う。複数のexampleで同一のインスタンスを使いたい場合、let
メソッドを利用することができる。
1 2 3 4 5 6 7 8 9 |
let
メソッドは呼び出された際に初めて実行される、遅延評価
という特徴を持っている。後述のbefore
メソッドが各exampleの実行前に毎回処理を行うのに対し、let
メソッドは初回の呼び出し時のみ実行される。複数回行われる処理を一度の処理で実装できるため、テストを高速にすることができる。また、一度実行された後は常に同じ値が返って来るため、テストで使用したいオブジェクトの定義に適している。
テストに必要なインスタンスが用意できたので、今度は「ログインをしている場合」「ログインをしていない場合」を実際に再現していく。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
require 'rails_helper'
describe MessagesController do
describe '#index' do
context 'log in' do
before do
login user
get :index, params: { group_id: group.id }
end
# この中にログインしている場合のテストを記述
end
context 'not log in' do
before do
get :index, params: { group_id: group.id }
end
# この中にログインしていない場合のテストを記述
end
end
|
before
ブロックの内部に記述された処理は、各exampleが実行される直前に、毎回実行される。before
ブロックに共通の処理をまとめることで、コードの量が減り、読みやすいテストを書くことができる。
「ログインをする」、「擬似的にindexアクションを動かすリクエストを行う」が共通の処理となるため、before
の内部に記述している。
deviseを用いて「ログインをする」ためのlogin
メソッドは、問題5で定義したもの。
1 2 3 4 5 6 |
module ControllerMacros
def login(user)
@request.env["devise.mapping"] = Devise.mappings[:user]
sign_in user
end
end
|
「擬似的にindexアクションを動かすリクエストを行う」ために、get
メソッドを利用。messagesのルーティングはgroupsにネストされているため、group_idを含んだパスを生成する。そのため、get
メソッドの引数として、params: { group_id: group.id }
を渡している。
ここまでで、各テスト共通の処理を定義することができた。
テスト本体の記述を行う。
- ログインしている場合
まず、アクション内で定義しているインスタンス変数があるかどうか確かめる。
インスタンス変数に代入されたオブジェクトは、コントローラのassigns
メソッド経由で参照できる。@message
を参照したい場合、assigns(:message)
と記述することができる。
1 2 3 4 5 6 7 |
it 'assigns @message' do
expect(assigns(:message)).to be_a_new(Message)
end
it 'assigns @group' do
expect(assigns(:group)).to eq group
end
|
@messageはMessage.newで定義された新しいMessageクラスのインスタンス。be_a_new
マッチャを利用することで、 対象が引数で指定したクラスのインスタンスかつ未保存のレコードであるかどうか確かめることができる。今回の場合は、assigns(:message)
がMessageクラスのインスタンスかつ未保存かどうかをチェックしている。
1 2 3 |
it 'assigns @group' do
expect(assigns(:group)).to eq group
end
|
@groupはeq
マッチャを利用してassigns(:group)
とgroup
が同一であることを確かめることでテストできる。
続いて、該当するビューが描画されているかどうかをテストする。
1 2 3 |
it 'renders index' do
expect(response).to render_template :index
end
|
expectの引数にresponse
を渡している。response
は、example内でリクエストが行われた後の遷移先のビューの情報を持つインスタンス。 render_template
マッチャは引数にアクション名を取り、引数で指定されたアクションがリクエストされた時に自動的に遷移するビューを返す。この二つを合わせることによって、example内でリクエストが行われた時の遷移先のビューが、indexアクションのビューと同じかどうか確かめることができる。
- ログインしていない場合
最後に、ログインしていない場合に、意図したビューにリダイレクトできているかをテストする。
1 2 3 |
it 'redirects to new_user_session_path' do
expect(response).to redirect_to(new_user_session_path)
end
|
redirect_to
マッチャは引数にとったプレフィックスにリダイレクトした際の情報を返すマッチャ。今回の場合は、非ログイン時にmessagesコントローラのindexアクションを動かすリクエストが行われた際に、ログイン画面にリダイレクトするかどうかを確かめる記述になっている。
各テストコードの記述が終わったら、テストを実行。
1 |
$ bundle exec rspec spec/controllers/messages_controller_spec.rb
|
以下のような結果になれば成功。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ bundle exec rspec spec/controllers/messages_controller_spec.rb
MessagesController
#index
log in
assigns @message
assigns @group
renders index
not log in
redirects to new_user_session_path
Finished in 0.22727 seconds (files took 3.8 seconds to load)
4 examples, 0 failures
|
メッセージを作成するアクション
- ログインしているかつ、保存に成功した場合
- メッセージの保存はできたのか
- 意図した画面に遷移しているか
- ログインしているが、保存に失敗した場合
- メッセージの保存は行われなかったか
- 意図したビューが描画されているか
- ログインしていない場合
- 意図した画面にリダイレクトできているか
問題7:messagesコントローラでメッセージを作成するアクションのテストを行う
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#〜省略〜
describe '#create' do
let(:params) { { group_id: group.id, user_id: user.id, message: attributes_for(:message) } }
context 'log in' do
before do
login user
end
context 'can save' do
subject {
post :create,
params: params
}
it 'count up message' do
expect{ subject }.to change(Message, :count).by(1)
end
it 'redirects to group_messages_path' do
subject
expect(response).to redirect_to(group_messages_path(group))
end
end
context 'can not save' do
let(:invalid_params) { { group_id: group.id, user_id: user.id, message: attributes_for(:message, content: nil, image: nil) } }
subject {
post :create,
params: invalid_params
}
it 'does not count up' do
expect{ subject }.not_to change(Message, :count)
end
it 'renders index' do
subject
expect(response).to render_template :index
end
end
end
context 'not log in' do
it 'redirects to new_user_session_path' do
post :create, params: params
expect(response).to redirect_to(new_user_session_path)
end
end
end
end
|
メッセージを作成するアクションでテストすべきは以下の点。
- ログインしているかつ、保存に成功した場合
- メッセージの保存はできたのか
- 意図した画面に遷移しているか
- ログインしているが、保存に失敗した場合
- メッセージの保存は行われなかったか
- 意図したビューが描画されているか
- ログインしていない場合
- 意図した画面にリダイレクトできているか
下記の条件に基づいて、context
でグループ分けする。
- ログインをしているかどうか
- メッセージの保存に成功したかどうか
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#〜省略〜
describe '#create' do
let(:params) { { group_id: group.id, user_id: user.id, message: attributes_for(:message) } }
context 'log in' do
# この中にログインしている場合のテストを記述
before do
login user
end
context 'can save' do
# この中にメッセージの保存に成功した場合のテストを記述
end
context 'can not save' do
# この中にメッセージの保存に失敗した場合のテストを記述
end
end
context 'not log in' do
# この中にログインしていない場合のテストを記述
before do
get :create, params: params
end
end
end
end
|
context
は、context
ブロックの内部でネストさせることができる。ネストさせることによって、ログインしている場合という条件の中で、さらに保存に成功した場合・失敗した場合を条件にグループを分けることができた。
3行目でlet
メソッドを用いてparams
を定義している。これは、擬似的にcreateアクションをリクエストする際に、引数として渡すためのもの。 attributes_for
はcreate
、build
同様FactoryBotによって定義されるメソッドで、オブジェクトを生成せずにハッシュを生成するという特徴がある。
1 2 3 4 5 6 7 8 |
$ rails c
[1] pry(main)> FactoryBot.build(:message)
=> #<Message:0x007fe0f0c42bf0 id: nil, content: "Quod suscipit aspernatur id delectus qui exercitationem.", image: nil, group_id: nil, user_id: nil, created_at: nil, updated_at: nil>
# オブジェクトを生成する
[2] pry(main)> FactoryBot.attributes_for(:message)
=> {:content=>"Quod suscipit aspernatur id delectus qui exercitationem.", :image=>#<File:/Users/yujimatsumoto/projects/a-project/public/images/no_image.jpg>}
# ハッシュを生成する
|
- ログインしているかつ、保存に成功した場合
まず、メッセージの保存ができているのかどうかを確かめる。
1 2 3 4 5 6 7 8 9 10 |
#〜省略〜
context 'can save' do
subject {
post :create,
params: params
}
it 'count up message' do
expect{ subject }.to change(Message, :count).by(1)
end
|
expectの引数として、subjectを定義して渡している。expectの引数が長くなってしまう際は、このようにして記述を切り出すことができる。このエクスペクテーションは、「postメソッドでcreateアクションを擬似的にリクエストをした結果」という意味になる。
createアクションのテストを行う際にはchange
マッチャを利用することができる。change
マッチャは引数が変化したかどうかを確かめるために利用できるマッチャ。change(Message, :count).by(1)
と記述することによって、Messageモデルのレコードの総数が1個増えたかどうかを確かめることができる。保存に成功した際にはレコード数が必ず1個増えるため、このようなテストとなる。
続いて、意図した画面に遷移しているかどうかを確かめる。
1 2 3 4 5 |
#〜省略〜
it 'redirects to group_messages_path' do
subject
expect(response).to redirect_to(group_messages_path(group))
end
|
createアクションを動かした際のリダイレクト先はgroup_messages_pathなので、上記の形でテストを行うことができる。
- ログインしているかつ、保存に失敗した場合 まず、メッセージの保存は行われなかったかどうかをテストしていく。
1 2 3 4 5 6 7 8 9 10 11 12 |
invalid_params
を定義する際に、attributes_for(:message)の引数に、content: nil
, image: nil
と記述している。
擬似的にcreateアクションをリクエストする際にinvalid_params
を引数として渡してあげることによって、意図的にメッセージの保存に失敗する場合を再現することができる。
Rspecで「〜であること」を期待する場合にはto
を使用するが、「〜でないこと」を期待する場合にはnot_to
を使用できる。not_to change(Message, :count)
と記述することによって、「Messageモデルのレコード数が変化しないこと ≒ 保存に失敗したこと」を確かめることができる。
続いて、意図したビューが描画されているかどうかを確かめる。
1 2 3 4 |
it 'renders index' do
subject
expect(response).to render_template :index
end
|
メッセージの保存に失敗した場合、indexアクションのビューをrenderするよう設定されているので、上記の形でテストを行うことができる。
- ログインしていない場合
最後に、非ログイン時に意図した画面にリダイレクトできているかどうかを確かめる。
1 2 3 4 5 6 7 |
context 'not log in' do
it 'redirects to new_user_session_path' do
post :create, params: params
expect(response).to redirect_to(new_user_session_path)
end
end
|
ログインしていない場合にcreateアクションをリクエストした際は、ログイン画面へとリダイレクトする。redirect_to
マッチャの引数に、new_user_session_pathを取ることで、ログイン画面へとリダイレクトしているかどうかを確かめることができる。
各テストコードの記述が終わったら、テストを実行する。
1 |
$ bundle exec rspec spec/controllers/messages_controller_spec.rb
|
下記のような結果になれば成功。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$ bundle exec rspec spec/controllers/messages_controller_spec.rb
MessagesController
#index
log in
assigns @message
assigns @group
redners index
not log in
redirects to new_user_session_path
#create
log in
can save
count up message
redirects to group_messages_path
can not save
does not count up
renders index
not log in
redirects to new_user_session_path
Finished in 0.32079 seconds (files took 3.97 seconds to load)
9 examples, 0 failures
|
テストのポイント
テストを記述していく上でのポイントは、以下のようになる。
- example1つにつき、結果を一つだけ期待している
- どのテストも明示的である
- 期待できる値が返ってくるときと、そうでないときを両方テストする
- FactoryBotを上手く利用して、すっきりとまとめる
- Fakerでダミーデータを作成する
- テスト内で使用する変数は、インスタンス変数として定義するのではなく、letを使用する
rspec参考
- 【rspec-rails】のGitHubページ https://github.com/rspec/rspec-rails
-
使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 https://qiita.com/jnchito/items/42193d066bd61c740612#subject-を使ってテスト対象のオブジェクトを1箇所にまとめる
-
- とても丁寧にRSpecの基本を説明した名記事。量が多いので、テストを記述していて詰まったときに呼んでみると回答への緒が見つかることが多い。
- Ruby on Rails、RSpecを使ってコントローラのテストを書いてみる https://blog.naichilab.com/entry/2016/01/19/011514
- コントローラのテストについて詳しくまとめてある。コントローラのテストを詳しく説明した記事は少ないので参考になる。