1

奇妙な問題。

Capybara と RSpec を使用してサインインをテストしようとしていますが、サインインするユーザーが認証されないように、Capybara が間違ったフィールドに入力しているようです。

FactoryGirl を使用してテスト ユーザーを作成しました。

#factories.rb

FactoryGirl.define do

    #...

    factory :user do
        name "guest"
        password "pwordtest"
        password_confirmation "pwordtest"
    end

end

次に、次のテストを作成しました (この問題をデバッグするために、多くの "puts" 要素が含まれています)。

#posts_spec.rb

describe "Valid post submission" do

 it "should log in a user and let him make a post" do
  User.destroy_all
  visit '/access' #My Login page
  user = FactoryGirl.create(:user)
  puts "name"
  puts user.name
  fill_in :name, with: "guest" # I did these literally to make sure FactoryGirl wasn't the problem.
  fill_in :password, with: "pwordtest"
  click_on "Log In"
  assert User.count == 1
  puts "authing test"
  current_path.should eq(new_post_path)
 end
#...
end

私のセッションコントローラで(より多くのデバッグ):

def create
    user = User.find_by_name(params[:name])
    puts "all"
    puts params
    puts "pre-inspect"
    puts user.inspect
    if user && user.authenticate(params[:password])
        session[:user_id] = user.id
      puts "In IF"
        redirect_to new_post_path
    else
        flash.now[:error] = "Invalid password/username combo."
      puts "there"
        render 'new' 
    end
  end

テストを実行しようとすると、次のエラーが発生します。

name
guest
all
{"utf8"=>"✓", "name"=>"pword", "password"=>"", "commit"=>"Log In", "action"=>"create", "controller"=>"sessions"}
pre-inspect
nil
there
authing test
F

Failures:

  1) Posts Valid post submission should log in a user and let him make a post
     Failure/Error: current_path.should eq(new_post_path)

       expected: "/posts/new"
            got: "/sessions"

       (compared using ==)
     # ./spec/requests/posts_spec.rb:28:in `block (3 levels) in <top (required)>'

言い換えれば、私のデバッグ プロンプトは、FactoryGirl ユーザーが正常であることを示唆していますが、どういうわけか、Capybara はこれらの値を適切なフィールドに割り当てることができないため、params (デバッグ出力の「all」の後) に「pword」が割り当てられます。名前として「guest」、パスワードとして「pword」の代わりに、名前と「」をパスワードとして使用します。その結果、テスト ユーザーは認証されず、セッションは開始されません。これは特に奇妙です。フィールドの名前が間違いなく正しいためです。

#sessions/new.html.erb

<div class="center_login">
    <h1>Log In</h1>
    <%= form_tag sessions_path do %>
      <div class="field">
        <%= label_tag :name %>
        <%= text_field_tag :name, params[:name] %><br />
      </div>
      <div class="field">
        <%= label_tag :password %>
        <%= password_field_tag :password %><br />
      </div><br>
      <div class="actions"><%= submit_tag "Log In", class: "btn" %></div>
    <% end %>
</div>

何が起こっているのか分かりますか?他の 2 人と私はこれを 1 時間以上いじりましたが、まったく理解できませんでした。

編集 - 実際の人間としてサイトをナビゲートすると、これはすべて完全に機能することに注意してください。のように、名前フィールドに入力したユーザー名とパスワード フィールドに入力したパスワードは、データベース内のものに対応しており、問題なくサインインしています。したがって、カピバラが正しいことを記入できなかったという私の疑いは、ここで誤りです。

編集 2 -- リクエストごとに、以下の 1 つのテストの Test.log 出力:

Connecting to database specified by database.yml
  [1m[36m (0.4ms)[0m  [1mbegin transaction[0m
Started GET "/posts/new" for 127.0.0.1 at 2013-02-14 07:29:55 -0800
Processing by PostsController#new as HTML
Redirected to http://www.example.com/
Filter chain halted as :authorize rendered or redirected
Completed 302 Found in 1ms (ActiveRecord: 0.0ms)
Started GET "/" for 127.0.0.1 at 2013-02-14 07:29:55 -0800
Processing by StaticsController#resume as HTML
  Rendered statics/_stars.html.erb (1.0ms)
  Rendered statics/_stars.html.erb (0.4ms)
  Rendered statics/_stars.html.erb (0.3ms)
  Rendered statics/_stars.html.erb (0.3ms)
  Rendered statics/_stars.html.erb (0.3ms)
  Rendered statics/_stars.html.erb (0.3ms)
  Rendered statics/_stars.html.erb (0.3ms)
  Rendered statics/_stars.html.erb (0.3ms)
  Rendered statics/_stars.html.erb (0.3ms)
  Rendered statics/_stars.html.erb (0.3ms)
  Rendered statics/_stars.html.erb (0.3ms)
  Rendered statics/_skills.html.erb (14.9ms)
  Rendered statics/_collapse_start.html.erb (0.6ms)
  Rendered statics/_collapse_start.html.erb (0.1ms)
  Rendered statics/_collapse_start.html.erb (0.1ms)
  Rendered statics/_collapse_start.html.erb (0.1ms)
  Rendered statics/_collapse_start.html.erb (0.1ms)
  Rendered statics/resume.html.erb within layouts/application (68.4ms)
  Rendered layouts/_shim.html.erb (0.2ms)
  Rendered layouts/_header.html.erb (1.0ms)
Completed 200 OK in 163ms (Views: 162.3ms | ActiveRecord: 0.0ms)
  [1m[35mUser Load (12.1ms)[0m  SELECT "users".* FROM "users" 
Started GET "/access" for 127.0.0.1 at 2013-02-14 07:29:55 -0800
Processing by SessionsController#new as HTML
  Rendered sessions/new.html.erb within layouts/application (1.2ms)
  Rendered layouts/_shim.html.erb (0.0ms)
  Rendered layouts/_header.html.erb (0.5ms)
Completed 200 OK in 32ms (Views: 32.1ms | ActiveRecord: 0.0ms)
  [1m[36m (0.1ms)[0m  [1mSAVEPOINT active_record_1[0m
  [1m[35mUser Exists (0.1ms)[0m  SELECT 1 AS one FROM "users" WHERE LOWER("users"."name") = LOWER('guest') LIMIT 1
Binary data inserted for `string` type on column `password_digest`
  [1m[36mSQL (30.0ms)[0m  [1mINSERT INTO "users" ("created_at", "name", "password_digest", "updated_at") VALUES (?, ?, ?, ?)[0m  [["created_at", Thu, 14 Feb 2013 15:29:55 UTC +00:00], ["name", "guest"], ["password_digest", "$2a$10$Y9NfnYjForrfufZOaqgQj.BdcHYLh.tkYomCVfHiJ4McbWMem445e"], ["updated_at", Thu, 14 Feb 2013 15:29:55 UTC +00:00]]
  [1m[35m (0.1ms)[0m  RELEASE SAVEPOINT active_record_1
Started POST "/sessions" for 127.0.0.1 at 2013-02-14 07:29:55 -0800
Processing by SessionsController#create as HTML
  Parameters: {"utf8"=>"✓", "name"=>"pword", "password"=>"[FILTERED]", "commit"=>"Log In"}
  [1m[36mUser Load (0.1ms)[0m  [1mSELECT "users".* FROM "users" WHERE "users"."name" = 'pword' LIMIT 1[0m
  Rendered sessions/new.html.erb within layouts/application (0.7ms)
  Rendered layouts/_shim.html.erb (0.0ms)
  Rendered layouts/_header.html.erb (0.5ms)
Completed 200 OK in 21ms (Views: 2.7ms | ActiveRecord: 0.1ms)
  [1m[35m (0.1ms)[0m  SELECT COUNT(*) FROM "users" 
  [1m[36m (0.5ms)[0m  [1mrollback transaction[0m

ご覧のとおり、セッション コントローラーに渡される「パラメーター」には、下から 6 行目で「pword」という名前 (およびフィルター処理された空のパスワード) が含まれており、これは奇妙でイライラさせられます。

EDIT 3 -- 私のテスト グループでは、最新バージョンの Capybara を使用しています。そして、この新しい投稿の時点で、別のコントローラーの仕様で本質的に同じ問題に遭遇しました。つまり、フィールド 1 に「A」、フィールド 2 に「B」、フィールド 3 に「C」を入力するようにカピバラに指示すると、そのコントローラーからのパラメーターは、フィールド 1 に「B」を入力し、フィールド 2 に「C」を入力します。 」 そして 3 は空で、あたかもカピバラが私が指示したフィールドのに各フィールドに入力しているかのようです。

編集 4 -- Dave S の提案に従って、サインイン プロセスのスクリーンショットを撮りました (また、編集 2 で述べたように、同じエラーが発生する投稿プロセスのスクリーンショットも撮りました)。

2 つの異なることが起こっています。ログインページでは、(パスワードがブロックされているため) 実際には正しい情報 (名前 == ゲスト、パスワード == 5 つ星、パスワード (およびゲスト) と同じ文字数) が入力されているように見えます。 )、しかし、スクリーンショットの代わりにページを保存してクリックスルーすると、テスターと同じようにセッションとエラーに移動します.

保存したページ/投稿ページのスクリーンショットで、カピバラは間違いなく間違ったフィールドに入力しています。名前フィールドには、コンテンツである必要があると言った内容が入力されており、コンテンツ フィールドは空です。これは、投稿用ではなくログイン用に新しい一意の ID を作成したためだと思います。両方に対してこれを行うとどうなるか見てみましょう。また、ブロックアウトされたときにパスワードを「ゲスト」と区別できるものに変更してから、報告します.

EDIT 5 -- 新しいスクリーンショット:

ここに画像の説明を入力

ここに画像の説明を入力

そして、2 つのビューのコードで、ここで何が違うのかがわかります。(スクリーンショットの (正しい) パスワードの長さを理解するために、上記のファクトリ コードも変更しました。

# new posts _form.html.erb
<%= form_for(@post) do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% @post.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name, id: "post_name" %>
  </div>
  <div class="field text-area">
    <%= f.label :content %><br />
    <%= f.text_area(:content, :size => '50x20', id: "post_content") %>
  </div>

    <div class="actions btn-group">
      <%= f.submit 'Post It', class: "btn" %>
    </div>

<% end %>

そしてログインします:

# login (new.html.erb in sessions)

<div class="center_login">
    <h1>Log In</h1>
    <%= form_tag sessions_path do %>
      <div class="field">
        <%= label_tag :name %>
        <%= text_field_tag :name, params[:name], id: "sessions_name" %><br /> 
        # The above name change seemed to possibly fix it. The weird thing, though, is that
        # a similar change in the posts form above did NOT fix that problem.
      </div>
      <div class="field">
        <%= label_tag :password %>
        <%= password_field_tag :password %><br />
      </div><br>
      <div class="actions"><%= submit_tag "Log In", class: "btn" %></div>
    <% end %>
</div>

これで (seesions_name というログイン名で)、ログインは 100% 機能します。パラメータは正しいなど。しかし、投稿はそうではありません。(本質的に同じ変更を行ったにもかかわらず)カピバラがまだ間違ったフィールドに入力しているためです。これのいずれかが問題をより明確にしますか? 私は困惑しています。

EDIT 6 -- 完全なレポはここにあります

4

2 に答える 2

0

アプリのログイン機能のテストで同様の問題が発生していました。手動でログインしたときは正常に機能しましたが、Capybara を使用してテストするとログインに失敗しました。

カピバラがフィールドに間違って入力するなど、私にはなかったいくつかの問題が発生しているようです。原因はわかりませんが、複数の問題が発生している可能性があります。デバッグ後、私の問題はバグのあるユーザー ファクトリが原因であることがわかりました。

私が持っていたのは:

「ダイジェスト/sha1」が必要

FactoryGirl.define do
  factory :user do
    login      'hitchcock'
    fname      'Alfred'
    lname      'Hitchcock'
    email      'alfred.hitchcock@example.com'
    password   Digest::SHA1.new << 'MacGuffin'
  end
end

パスワードを設定するフィールドが正しくありませんでした。これは正しいバージョンです:

    password   (Digest::SHA1.new << 'MacGuffin').to_s

クラス User の「パスワード」フィールドには、実際にはパスワードではなくパスワード ダイジェストが含まれていますが、私はレガシー データベースを使用しています。いずれにせよ、パスワードのダイジェストを間違って計算し、to_sメソッドを忘れていたため、ユーザー名「hitchcock」とパスワード「MacGuffin」を使用したテスト ケースのログイン試行が失敗しました。

さて、あなたの工場を見ると、あなたも同様の問題を抱えているように思えます。移行ファイル20130206234907_create_users.rbは次のようになります。

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.string :password_digest
      t.timestamps
    end
  end
end

これは、正しく適切なパスワード自体ではなく、パスワードのダイジェストを保存していることを示しています。ただし、ファイル内のユーザー ファクトリfactories.rbは次のとおりです。

factory :user do
  name "guest"
  password "pwordtest"
  password_confirmation "pwordtest"
end

ファクトリは、作成するユーザーのpassword_digestフィールドを指定していないため、コマンドでposts_spec.rbユーザーを作成するときに

user = FactoryGirl.create(:user)

ユーザーがデータベースに作成されているのか、それとも作成されている場合、そのpassword_digestフィールドはどうなるのだろうか? テストを実行すると、テスト データベースの内容が最初にクリアされるので、テスト コードがデータベースに有効なユーザーを作成しないと、ログイン テストが機能しないことに注意してください。

于 2013-02-20T15:13:57.787 に答える