3

更新:スペック/コントローラーではなくスペック/リクエストにスペックが含まれるようになったため、スペックがどのように機能するかについては、投稿の終わりを参照してください。コントローラーとの統合テストのために、有効なサインインユーザーを取得する方法をまだ考えています。

私は初めてDeviseとCanCanを使用していますが、最も基本的な統合テストを実行するのに苦労しています。これにより、ログインしているユーザーが...まあ...ログインしていることを確認しています。 DeviseとRSpecの統合テストに関する回答(つまり、https //github.com/plataformatec/devise/wiki/How-To%3a-Test-with-Capybara、http://schneemsから直接セッションにアクセスしてスピードアップする) .com / post / 15948562424 / speed-up-capybara-tests-with- devise 、およびCapybara、RSpec、Devise:遅いログインを回避してセッションを直接設定することで統合テストを高速化する方法はありますか?標準の投稿が期待どおりに機能するようになり、困惑しました。

  1. 開発環境は正常に機能します(ログインして適切なページにリダイレクトされ、ナビゲーションログインリンクがログアウトに変更されるなど)。
  2. test.logは、root_pathではなくhttp://www.example.comに302リダイレクトするまで、問題がないことを示しています。

さまざまな解決策で同様の問題を抱えている多数のユーザーによって、セッションなどのさまざまな側面がさまざまなシナリオで利用できないため、この問題を抱えているのは明らかに私だけではありません。

ストリップダウンテスト:

subject { page }

describe 'should be able to log in' do
  before do
    visit '/users/sign_in'
    user = FactoryGirl.create(:admin)
    #user.add_role :admin
    fill_in 'Username', with: user.username
    fill_in 'Password', with: user.password
    click_on 'Sign in'
  end
  it { should have_link 'Logout' }
end
...

関連するlog.testの出力:

 Started POST "/users/sign_in" for 127.0.0.1 at 2012-11-06 17:31:10 -0800
 Processing by Devise::SessionsController#create as HTML
 Parameters: {"utf8"=>"✓", "user"=>{"username"=>"username1", "password"=>"[FILTERED]",        "remember_me"=>"0"}, "commit"=>"Sign in"}
 [1m[36mUser Load (0.1ms)[0m  [1mSELECT "users".* FROM "users" WHERE "users"."username" =   'username1' LIMIT 1[0m
 [1m[35m (0.0ms)[0m  SAVEPOINT active_record_1
    [1m[36m (0.0ms)[0m  [1mRELEASE SAVEPOINT active_record_1[0m
 [1m[35m (0.0ms)[0m  SAVEPOINT active_record_1
 [1m[36m (0.1ms)[0m  [1mUPDATE "users" SET "last_sign_in_at" = '2012-11-07   01:31:10.722712', "current_sign_in_at" = '2012-11-07 01:31:10.722712', "last_sign_in_ip" =   '127.0.0.1', "current_sign_in_ip" = '127.0.0.1', "sign_in_count" = 1, "updated_at" = '2012-11-  07 01:31:10.723051' WHERE "users"."id" = 1[0m
 [1m[35m (0.0ms)[0m  RELEASE SAVEPOINT active_record_1
 Redirected to http://www.example.com/
 Completed 302 Found in 12ms (ActiveRecord: 0.0ms)

削除されたroutes.rb:

authenticated :user do
  root :to => 'home#index'
end
root :to => "home#index"
devise_for :users
resources :users

能力を取り除いた:

クラス能力にはCanCan::Abilityが含まれます

 def initialize(user)
  user ||= User.new # guest user (not logged in)
  if user.has_role? :admin
    can :manage, :all
  end
  ...

そして徹底的に、現在のGemfile:

source 'https://rubygems.org'

gem 'rails', '3.2.8'
gem "bootstrap-sass", "~> 2.1.0.1"
gem 'faker', '1.1.2'
gem 'will_paginate', '~> 3.0.3'
gem 'bootstrap-will_paginate', '~> 0.0.9'
gem 'jquery-rails'
gem 'client_side_validations'
gem 'thin'
gem "devise", "~> 2.1.2"
gem "cancan", "~> 1.6.8"
gem "rolify", "~> 3.2.0"
gem "simple_form", "~> 2.0.4"

group :assets do
   gem 'sass-rails',   '~> 3.2.3'
   gem 'coffee-rails', '~> 3.2.1'
   gem 'uglifier', '>= 1.0.3'
end

group :development, :test do
 gem 'sqlite3', '1.3.5'
 gem "rspec-rails", "~> 2.11.4"
 gem 'guard-rspec', '1.2.1'
 #gem 'listen', github: 'guard/listen', branch: 'polling/double'
 gem 'guard-spork'
 gem 'guard-cucumber'
 gem 'spork', '0.9.2'
 gem "factory_girl_rails", ">= 4.1.0"
end

group :development do
  gem 'annotate', '2.5.0'
  gem "quiet_assets", ">= 1.0.1"
end

 group :test do
  gem 'capybara', ">= 1.1.2"
 gem "email_spec", ">= 1.2.1"
 gem "cucumber-rails", ">= 1.3.0", :require => false
 gem "database_cleaner", ">= 0.9.1"
 gem "launchy", ">= 2.1.2"
 gem 'rb-fsevent', '0.9.1', :require => false
 gem 'growl', '1.0.3'
 gem 'terminal-notifier-guard'
end

group :production do
    gem 'pg', '0.12.2'
 end

この基本的なタスクで問題が発生した別のユーザーがいますが、それは単なる構文エラーであることが判明したため(rspec / deviseを使用したログイン統合テストを参照)、非常に明白な何かが欠けていると確信しています。

アップデート:

あなたは私をからかっていなければなりません。数時間放置した後、スペック/コントローラーに何らかの理由でこのスペックがあったことがわかりました。スペック/リクエストに切り替えるだけで、すべてがグリーンになりました。

私は引用します:

Railsを使用している場合は、Capybaraの仕様をspec/requestsまたはspec/integrationに入れてください。

https://github.com/jnicklas/capybara#readmeで見つかりました

ただし、将来の要件について、ログインユーザーが必要なコントローラーで統合テストを実行する方法についてはまだ疑問に思っています。過去の他の非デバイスアプリの場合、これは次のような単純なものでした。以下:

describe SomeController do

  let(:user) { FactoryGirl.create(:user) }

  before { valid_sign_in user }

...

私のヘルパーは単に

  def valid_sign_in(user)
    visit signin_path
    fill_in "Email", with: user.email
    fill_in "Password", with: user.password
    uncheck(:remember_me)
    click_button "Sign In"

    # Sign in when not using Capybara as well.
    cookies[:remember_token] = user.remember_token
  end
4

1 に答える 1

5

2つの問題があります。

1. rspec/controllerとrspec/requests

私はスペック/コントローラーの下で統合テストを行おうとしていました。https://github.com/jnicklas/capybara#readmeに従って、Capybaraの仕様をspec/requestsまたはspec/integrationに配置する必要があります。https://stackoverflow.com/a/5803121/9344によると:

リクエスト仕様は、ActionDispatch :: IntegrationTestの薄いラッパーであり、コントローラー仕様(ActionController :: TestCaseをラップする)のようには機能しません。利用可能なセッションメソッドはありますが、サポートされているとは思いません(つまり、他のユーティリティに含まれるモジュールにもそのメソッドが含まれているため、おそらくサポートされています)。

もともとこれは、次のようなヘルパーメソッドを介してDeviseで解決できました。

# file: spec/requests_helper.rb
def login(user)
  post_via_redirect user_session_path, 'user[email]' => user.email, 'user[password]' => user.password
end

しかし、私がすでに実装した公式/最新のソリューション(ただし、問題が解決しなかった理由については、以下のポイント2を参照してください)は、https://github.com/plataformatec/devise/wiki/How-Toにあります。 :-カピバラでテスト

2. Devise :: HelperTestsは、統合テストではなく、コントローラー/ビューテスト用です。

コントローラーでいくつかのテストを実行したい場合は、Devise :: TestHelpers(spec_helper.rbを介して参照)を使用できますが、Devise :: TestHelpersはコントローラー用に特別に作成されているため、Capybara統合テストの機能を取得できません。 / viewテストであり、統合テストではありません。rspec&deviseテストヘルパーを参照してください。

要約すると、コントローラーテストでやりたかったことは、実際には統合テストであり、セッションなどがスペック/コントローラーで使用できないため、実行できません。ただし、コントローラー/ビューのテストを支援するために使用できるDeviseテストヘルパーがいくつかあります。

アップデート

私はこれをずっと後で再検討し、統合テストでWardenヘルパーが機能するようになりました。フラ!これは私の448テストで8-10秒離陸しました。トリックはhttps://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybaraの新しいエントリでした。具体的には:

カピバラ-Webkit

capybara-webkitドライバーでWardenのlogin_asメソッドを使用する際に問題が発生した場合は、login_asオプション構造体でrun_callbacksをfalseに設定してみてください。

user = Factory.create(:user) 
login_as(user, :scope => :user,
:run_callbacks => false)

要約すると、統合テストのために認証されたユーザーが必要になるたびに実際のフォーム入力と投稿を行う代わりに、今は必要なだけですlogin_as(user, :scope => :user, :run_callbacks => false)(もちろんヘルパーメソッドにリファクタリングされています)。

于 2012-11-07T17:54:16.483 に答える