はじめに
Ruby on Railsでポートフォリオを作成している、Ruby初学者です。
CarrierWaveで画像アップロード機能を実装されている方も多いかと思います。私もその一人です。
ユーザのアバター設定や投稿時の画像添付などでこのgemを使用しており、各種テストにも確認のためCarrierWaveの画像アップロード機能を含めていました。
ポートフォリオ作成中、テストを何回か回したあと、たまたま画像を保存しているフォルダをみてみると、・・・・フォルダ数600!?
全然気づいていませんでした。テストを回せばその分テストケースに含まれている画像アップロードも何度も何度も実行されます。いつのまにか、私のフォルダは画像の容量で逼迫していました・・・
手動で消す事もできますが、テストはリファクタリングや機能追加毎に実行しますし、それだとかなり面倒です。
というわけで、テスト実行後にテスト用に作られたCarrierWaveの画像を消すように設定していきます。
環境
Docker内にコンテナを作成してrails開発をしています。
Docker for mac 2.3.0.4
Ruby on Rails 5.2.2
ruby 2.4.5
CarrierWave 2.1.0
答えはCarrierWaveのWikiに
参考にしたのは、CarrierWaveのwikiの以下のページ
How to: Cleanup after your Rspec tests
これを参考にしながら、以下の流れで消去します。
1. test時のアップロードフォルダを指定する(uploeaderファイル)
2. rspecテストの実行後に、指定したパスのフォルダを全て消去するようにする
1.テスト時のアップロードフォルダ指定
キャッシュファイルもいくつか生成されるため(エラーチェックのテストケース時に)
キャッシュとストア両方のフォルダを指定します。
:
#キャッシュのフォルダを指定
def cache_dir
if Rails.env.test?
"uploads/#{Rails.env}/tmp/#{mounted_as}/#{model.id}"
else
"uploads/tmp/#{mounted_as}/#{model.id}"
end
end
#storeのフォルダを指定
def store_dir
if Rails.env.test?
"uploads/#{Rails.env}/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
else
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
:
2.rspecテストの実行後に、指定したパスのフォルダを全て消去するようにする
上で指定したキャッシュとストアフォルダを一気に削除するようパスを書く。
:
config.after(:all) do
if Rails.env.test?
FileUtils.rm_rf(Dir["#{Rails.root}/public/uploads/#{Rails.env}/"])
end
end
:
これでrspecテストを流す毎に自動的にテスト用フォルダを消去してくれます。
おわりに
テストを何度も回して、フォルダが大量に出来てしまったり、容量を逼迫することはなくなりましたが、
消去というプロセスがテストに入ったことにより、多少rspecの処理スピードが遅くなってしまった印象。
これはどうしようもないのでしょうが、テスト時に本当に画像アップロードが必要かどうかは見分けて、不要であれば画像なしでfactoriesを作ることも検討した方がいいですね。テストケースの見直しも行いたいと思います。