初めに
前回の結合テストコードの書き方(新規登録に関するテストコード)に引き続き
今回は画像投稿機能の結合テストコードを実装しました。
次の機会に行う際、抜け漏れがないよう記録していきたいと思います。
結合テストコードを書く手順
①結合テストコードを書くためのファイルを生成する
今回は画像投稿機能に関する結合テストコードを書いていきます。
% rails g rspec:system items
生成されたファイル
spec/system/items_spec.rb
以下のようなファイル構成になっていれば成功です。
🗂 spec
∟ 🗂 factories
🗂 models
🗂 requests
🗂 system
∟ users_spec.rb ←前回生成したファイル
∟ items_spec.rb ←生成されたファイル
②exampleを整理する
ユーザー目線で考え、「ユーザーがブラウザでどのような操作をすると、どうなるのか」を考えます。
例 投稿に関する結合テストコード
・投稿できるとき
正しい情報を入力すれば投稿できてトップページに移動する
・登録ができないとき
誤った情報では投稿できずに投稿ページへ戻ってくる
この動作を1つ1つ細かく洗い出して、テストコード内に落とし込みます。
③「ログインする」という流れをサポートモジュールにまとめる
今後投稿機能の他に、編集機能や削除機能を追加しようと考えています。
全ての機能で「ログインしている場合」という条件が出てくるため、
「ログインする」という流れをサポートモジュールにまとめます。
詳しくは以下の記事でご紹介しています。
【Rails/System Spec】サポートモジュールで結合テストコードの記述を短くする(ログイン動作をまとめる)
③洗い出した条件を書く
条件がイメージがしづらい時
実際にアプリで「新規投稿」をしてみて、「どのページにいるか」「どのボタンを押すと遷移するか」「どこに何を入力する必要があるか」などを意識して操作すると考えやすくなるのでおすすめです。
※FactoryBotで新規登録(@user)、新規投稿(@item)に必要な情報を定義しておきます。
require 'rails_helper'
RSpec.describe '新規投稿', type: :system do
before do
@user = FactoryBot.create(:user)
@item = FactoryBot.create(:item)
end
context '新規投稿ができるとき'do
it 'ログインしたユーザーは新規投稿できる' do
# トップページに移動する
# ログインする
# 投稿ページに移動する
# フォームに情報を入力する
# 送信するとItemモデルのカウントが1上がることを確認する
# トップページに遷移する
end
end
context '新規投稿ができないとき'do
it 'ログインしていないと新規投稿ページに遷移できない' do
# トップページに遷移する
# 新規投稿ページへのボタンがないことを確認する
end
end
end
中身を書く前にテストコードを実行します。
% bundle exec rspec spec/system/items_spec.rb
緑色の表示の場合は、テストが正しく通ったことを示しています。
次は中身を書いていきましょう。
補足:なぜ中身を書く前に、テストコードを実行するの?
理由はエラーの特定がしやすくなるためです。
テストコードは入れ子構造を使っているため、endが抜けるなど文法エラーが出やすい箇所だと感じています。
例 endが足りない場合のエラー
続き syntax error, unexpected end-of-input, expecting end
1度テストコードを実行することで「ここまではエラーはなし」という確認につながるので、
もし以降にエラーが出た場合「この記述以降の箇所でのエラー」と、特定がしやすくなります。
④ 実際の結合テストコード
require 'rails_helper'
def basic_pass(path) #--①説明
username = ENV['BASIC_AUTH_USER']
password = ENV['BASIC_AUTH_PASSWORD']
visit "http://#{username}:#{password}@#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}#{path}"
end
RSpec.describe '新規投稿', type: :system do
before do
@user = FactoryBot.create(:user)
@item = FactoryBot.build(:item)
end
context '新規投稿ができるとき'do
it 'ログインしたユーザーは新規投稿できる' do
# ログインする
sign_in(@user)
# 投稿ページに移動する
visit new_item_path
# フォームに情報を入力する
attach_file '作品', "#{Rails.root}/spec/fixtures/test_sample.png" #--②説明
fill_in 'コメント', with: @item.text
fill_in '作った年齢(半角数字)', with: @item.age
fill_in '材料', with: @item.material
fill_in '作り方', with: @item.making
# 送信するとItemモデルのカウントが1上がることを確認する
expect{
find('input[name="commit"]').click
}.to change { Item.count }.by(1)
# トップページに遷移する
visit root_path
end
end
context '新規投稿ができないとき'do
it 'ログインしていないと新規投稿ページに遷移できない' do
# トップページに遷移する
basic_pass root_path
# 新規投稿ページへのボタンがないことを確認する
expect(page).to have_no_content('投稿する')
end
end
end
--① Basic認証
Basic認証を交えたテストコードの書き方を参考にさせていただきました。
--② Active Storageを使用した画像添付
画像更新のテストが通らないという質問を参考にさせていただきました。
具体的な方法
①specディレクトリに、fixturesディレクトリを作成し、画像を配置する
🗂 spec
∟ 🗂 factories
🗂 models
🗂 requests
🗂 fixtures ←ディレクトリを作成する
∟ test_sample.png ←画像を配置する(画像名は任意でOK)
🗂 system
∟ users_spec.rb
∟ items_spec.rb ←今回生成したファイル
②Active Storageを使用した記述を追加
attach_file '作品', "#{Rails.root}/spec/fixtures/test_sample.png"
#''内はラベル名を入力
※ディレクトリ名や画像名は適宜該当する名前に置き換えて記述ください。
※ラベル名に該当する場所が分からない場合はこちらの「実際にフォームへの入力を行う」をご参照ください。
⑤テストコードを実行する
% bundle exec rspec spec/system/items_spec.rb
テストが正しく通ったことを示す緑色の表示の場合は完了です。
お疲れ様でした
まとめ
最後までご覧くださり、ありがとうございました。
今回は投稿機能の結合テストコードの実装記録でした。
初学者のため、記入漏れや記述ミスがありましたら教えていただけると助かります。
こちらの記事がどなたかの参考になりましたら幸いです。
関連
【RSpec / Rails】サポートモジュールで結合テストコードの記述を短くする(ログイン動作をまとめる)
【Rails/System Spec/Capybara】結合テストコードを書くときによく使う表現 一例
【Rails】結合テストコードの書き方(新規登録に関するテストコード)