はじめに
調べたところによると、Capybaraでは画像アップロードテストにattach_file([locator], paths, **options)
を使えということだったのですが、なんかうまくいかなかったので別の方法でテストしてみました。
コード
設定画面等で画像をアップロードすると、マイページに反映されるようなテストを想定します。
Qiitaも同じで、プロフィール設定で画像をアップロードすると右上のプロフィール画像が変わります。これのテストです。
input#input-image type="file" name="avatar" accept="image/jpeg"
scenario '画像をアップロードするとマイページに反映される' do
using_session(@user.name) do
visit 'path/to/target'
image_path = File.join(Rails.root, "spec/factories/images/img.jpg")
page.('#input_image').set(image_path)
update_profile(page)
expect(page).to have_selector("img[src$='img.jpg']")
end
end
using_session
はCapybaraのこのセッションを使うよってやつですね。ここには入れてませんが、beforeの処理でこのユーザーはログイン済みです。
visit 'path/to/target'
で好きなページにアクセスします。
image_path
はそのままですね。画像のパスです。
そして重要なのがpage.('#input_image').set(image_path)
です。attach_file
ではなく、setを使っています。正直この2つの違いが分かりませんが、setはinputに入力しているだけなので、ファイルだけではなく、textであってもsetの中身が入力されます。
画像を選んだらupdate_profile(page)
でプロフィールを更新し、expect(page).to have_selector("img[src$='img.jpg']")
でsrc属性にimg.jpgを含むimgタグがあるかを確認しています。$=
とすることでその後に続く文字列を含むものを探します。
今回はimg.jpgをアップロードしたので、同じ名前のjpgファイルを探して、指定したurlにその属性があるかどうかをテストしています。
注意点
基本的にテストは使い捨てなので、テスト上で行われたDBの操作、例えばユーザー名の変更などはそのテストが終われば元に戻りますが、今回の場合画像をセットしているため、ユーザーの画像が置いてあるディレクトリの画像が置き換わっています。そのため、1回テストが完了すると、テストによっては初期の画像を読み込めずエラーを起こす場合がありますので、手動で画像を入れ替えるか、テスト用DBを初期化してください。
まとめ
attach_fileが上手くいかない時は試してみると良いかもしれません。