何をやるのか、とその前提
最終目的
この記事では、RSpecを用いて画像投稿のテスト、対象モデルのバリデーションテストを行う手順を解説していきます。
画像は単数でのテストとなりますが、このやり方を応用すれば複数画像の投稿テストも可能です。
「複数画像のテストをやりたいんだ!」という人も、ぜひ一読いただき、自分の環境で応用できないか試してみてください。
前提条件
Rails で画像を扱うのに、専用のgemを入れてコーディングする場合も多いです。
なので、この記事での手順は、“refile”や“carrierwave”などのgemを使用して実装している前提とします。
また、作成しているアプリの方では既に画像アップロード周辺の機能を実装済みとします。
テストコードの書き方
画像を保存しているカラムについて
今回は users テーブルに紐づく形で、画像を登録する設定とします。
このとき、モデルでは以下のように “profile_image” などの任意の名称で画像を保存するカラムを指定します。
これで user と紐づいた形で profile_image に画像が保存されるようになりますが、前述の gem を使用している場合は、schemaファイルに profile_image カラムが現れません。
これは gem の仕様で、内部的に画像保存用カラムを持っているので、実際にDBを見ると定義されていることが確認できます。
下準備
実際にテストコードを書いていく前に、少し準備をする必要があります。
画像を配置
まず、テストで使用する画像をあらかじめどこかに置いておきます。
今回は以下のパスでフォルダを作成し、「test.jpg」というファイルを用意しました。
※画像ファイルの拡張子は png などでも構いません。
spec/fixtures/images/test.jpg
FactoryBot でダミーデータを定義
次にダミーデータの定義です。
“factory_bot_rails”のgemを使うので、以下のようにGemfileに追加し、bundle install しておいてください。(既にあれば追加不要です)
そして FactoryBot で以下のようにファイルを作成して、ダミーデータを定義しておきます。
モデルのバリデーションテスト
それではモデルのテストを以下のように書いていきます。
User モデルで指定していた、profile_image のカラムに対して画像を指定する内容となっています。
下記の部分が、画像をアップロードしてバイナリ形式でプログラムが処理できるようにする、というものです。(まあ呪文のようなものだと思ってください笑)
Rack::Test::UploadedFile.new(File.join(Rails.root, 'spec/fixtures/images/test.jpg'))
これでテストを実行すると、バリデーションがOKでテストをパスします。
フォーム画面から画像登録のテスト
次に、画像をフォーム画面から投稿するテストコードの書き方を解説します。
専用のgemをインストール
画面を操作したように振る舞うテストを実行するために、”capybara”というgemを使用します。
Gemfile に以下を追加し、bundle install してgemを入れてください。
画面操作のテスト
以下のパスのように、フォルダとファイルを作成します。(ファイル名はなんでもOKです)
このテストの流れは、大きく以下のようになっています。
- FactoryBotで定義したデータをuser変数に展開する
- ユーザー情報編集画面に遷移する
- 更新前の profile_image の内容を変数に持っておく
- フォーム上で profile_image に画像を選択した状態にする
- 更新ボタン(“Update User”)を押す
- user変数の profile_image が、更新前と異なっていることを確認する
特に、以下の部分は少し注意が必要で、モデルの画像テストで使用したコードと少し異なっています。
attach_file 'user[profile_image]', File.join(Rails.root, 'spec/fixtures/images/test.jpg')
これはフォームの input要素に対して、ファイルの場所を教えてあげているだけで、実際にファイルを取得してバイナリ形式で処理するのはコントローラーになるので、ここでは場所を教えているだけなんです。
なお、’user[profile_image]’ となっている箇所はフォームで input となっているものの name 属性に指定している名前を書くようにしてください。
まとめ
RSpec での画像テストのやり方を解説しました!
今回は user モデルに画像が紐づく形となっており、ざっくりまとめると以下のような流れでテストができました。
- 必要なgemを入れておく
- テストに使う画像を用意する
- FactoryBot でダミーデータを定義する
- モデルのバリデーションテストを書く
- capybara で画面操作のテストを書く
- テスト実行
この記事では画像1つでの例でしたが、このやり方を応用すれば、画像が複数の場合のテストも可能ですので、ぜひ試してみてください。
コメント