Rails + RSpec + Capybara で Devise での認証ログインが必要なインテグレーションテスト(RequestSpec)を行う

スポンサーリンク

Rails で Devise で認証機能を作り、テストに RSpec を使う場合、sign_in, sign_out のテストヘルパーが使えます。詳細は以下ページのテストヘルパー(RSpec)の項目を参照。

Rails4 にて Devise でユーザー登録・ログイン認証・認可の機能を追加 | EasyRamble

【お知らせ】 英単語を画像イメージで楽に暗記できる辞書サイトを作りました。英語学習中の方は、ぜひご利用ください!
画像付き英語辞書 Imagict | 英単語をイメージで暗記
【開発記録】
英単語を画像イメージで暗記できる英語辞書サービスを作って公開しました
スポンサーリンク

しかし、これらの sign_in, sign_out のヘルパーは、Capybara や Webrat を用いた integration tests(インテグレーションテスト)では動作せず、fuctional tests だけで動作するという注意点があります。サインインさせる場合は、代わりにフォームを埋めるか明示的にセッションをセットする必要がある。

以上の注意点より、spec/requests 内のインテグレーションテスト(結合テスト:RequestSpec)を行う場合は、工夫が必要となります。

— 環境 —
rails-4.0.1
devise-3.2.2
rspec-rails-2.14.0
capybara-2.2.0

インテグレーションテストの雛形を生成

まずは、インテグレーションテスト(RequestSpec)の雛形を生成。

spec/requests/user_registration_pages_spec.rb

Devise で管理される Users::RegistrationsController (Devise::RegistrationsController を継承したクラス) に関するインテグレーションテスト。

spec/requests/user_session_pages_spec.rb

Devise で管理される Users::SessionsController (Devise::SessionsController を継承したクラス) に関するインテグレーションテスト。

spec/requests/user_pages_spec.rb

Devise とは別に作成する users#index, users#show に相当するコントローラーに関するインテグレーションテストを行う。

これらテスト用ファイルは、私は Devise のコントローラーに準じて生成しましたが、好きなように作って良いと思います。spec/requests 内のこれらのインテグレーションテスト(RequestSpec)で、Devise で用意される sign_in ヘルパーを使うと以下のエラー(NoMethodError)が発生しました。冒頭に書いた注意のとおりです。

ControllerMacros モジュールを作成する方法(※ ControllerSpec でのみ動作)

以下を参考に、ControllerMacros を作成する方法を最初に試しました。

How To: Controllers tests with Rails 3 (and rspec) · plataformatec/devise Wiki · GitHub

spec/support/controller_macros.rb

spec/spec_helper.rb

Devise のテストヘルパーの sign_in メソッドを使っているので、RequestSpec では動作しないだろうなと予想していたら、案の定動作しませんでした。ControllerSpec(spec/controllers 内)でのコントローラーのテストだと動作する模様です。RequestSpec では動作しなかったので、以下の代替案でインテグレーションテストを行いました。

Warden::Test::Helpers の login_as メソッドを利用する

参考にしたのは、以下のページ。

RequestSpecでDeviseを使ったユーザーでログインさせる | 自転車で通勤しましょ♪ブログ
rspec-rails (2.14.0) + devise (3.2.1, 3.2.0) + capybara (2.2.0) でsign in判定 – ryutamaki

Warden::Test::Helpers の login_as メソッドを用いて、独自の login(user) メソッドを定義します。テスト内でユーザーをログインさせる場合、この login メソッドを使います。

spec/support/request_helpers.rb

spec_helper.rb で RequestHelpers モジュールをインクルードします。

spec/spec_helper.rb

最後に、インテグレーションテスト(RequestSpec)の例として以下を書きました。Devise のテストヘルパーである sign_in の代わりに、独自に定義した login メソッドを用います(login user の箇所)。

spec/requests/user_registration_pages_spec.rb

sign_in メソッドの代わりに login を使ったところ、NoMethodError も発生せず、テストのユーザーをログインさせることができ、無事にテストを通りました。

Stackoverflow で post メソッドを使う方法も見つけました(参考リンクの一番下)。試してませんけど、こちらのほうが簡単かもです。

スポンサーリンク
私は Rails のテストフレームワークには RSpec を使っています。サーバーのテスト用に Serverspec もおすすめです。
 
スポンサーリンク

Leave Your Message!