1

奇怪的问题。水豚填写错误的领域

我正在尝试使用Capybara和RSpec测试登录,但似乎Capybara正在填写错误的字段,以便用户登录未被验证。

我使用FactoryGirl创建测试用户:

#factories.rb 

FactoryGirl.define do 

    #... 

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

end 

然后我写了下面的测试(有很多的“看跌期权”的东西在里面,调试这个问题):

#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 

当我尝试运行测试时,出现以下错误R:

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用户是好的,但不知何故,水豚在调试未能分配这些值的权利领域,使PARAMS(在“全”打印)被指定为“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 - 下面一个测试的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 

正如你可以看到,传递给会话控制器从底部6ish线“参数”包括名称“ pword“(以及过滤后的可能为空的密码),这很奇怪/令人沮丧。

编辑3 - 在我的测试组中使用最新版本的水豚。而就这个新帖子来说,我已经遇到了另一个控制器规格中基本相同的问题。也就是说,我会告诉Capybara填写“A”的字段1,填写“B”的填写2,填写“C”的填写3,填写“C”的填写“2”的填写的填写“2” “和3空,好像水豚是填写每个领域之前到我告诉它或某事。

编辑4 - 遵循Dave S的建议,我截取了登录过程(以及发布过程,如编辑2中所述,具有相同错误)的屏幕截图。

发生了两件不同的事情!在登录页面中,它看起来像(因为密码被阻止),它实际上填充了正确的信息(名称==客人,密码==五颗星,与密码(和客人)相同的字符数) ),但如果我保存一个页面而不是截图并单击,它会像测试人员一样进入会话和错误。

在投稿页面自己保存的网页/屏幕截图,水豚是绝对错误的领域填充。名称字段充满了我所说的内容,内容字段为空。我认为这是因为我为登录创建了新的唯一ID,但不能发布,我会看到如果我为两者做了这些,会发生什么。我还会在密码被锁定时将密码更改为与“guest”不同的内容,然后再回报。

编辑5 - 新的截图:

enter image description here

enter image description here

和两个视图代码,给的可能是什么不同,这里的感觉。 (我也改变了上述工厂代码变得有意义了(正确的)密码长度的截图

# 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%。该PARAMS是正确的,等等,但帐不会,因为(尽管我作出基本相同的变化)水豚在错误的领域仍然充盈,是否有这使问题更清楚?我难倒。

编辑6 - 可以找到完整的回购here

+1

你在Rails日志(test.log)中看到什么,发布什么?你确定字段id实际上是'名字'和'密码'吗?当您在new.html.erb硬编码ID中给出这两个字段时会发生什么? – Bitterzoet 2013-02-14 13:48:15

+0

是的。其实。我忘了张贴,但这是最初导致我的理论。我将通过该测试发布与一次运行相关的整个日志。 – Sasha 2013-02-14 15:28:28

+0

这么好的建议 - 在字段中添加ids sessions_name和sessions_password并引用这些id在水豚中解决了问题(如果我可以授予您的评论作为正确的答案,我会),但我仍然很想知道为什么这是继续。 – Sasha 2013-02-14 15:36:45

回答

0

我只是有一个类似的问题,测试我的应用程序的登录功能:手动登录时工作正常,但使用Capybara测试时登录失败。

你似乎有一些问题,我没有,即,水豚充盈领域不正确。我不确定这是因为什么,但你可能会遇到不止一个问题。调试后,我发现我的问题是由于一个错误的用户工厂。

我有什么:

需要 '消化/ SHA1'

FactoryGirl.define do 
    factory :user do 
    login  'hitchcock' 
    fname  'Alfred' 
    lname  'Hitchcock' 
    email  '[email protected]' 
    password Digest::SHA1.new << 'MacGuffin' 
    end 
end 

,设置密码不正确的字段。这是正确的版本:

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

类用户的“密码”字段实际上包含一个密码摘要,而不是一个密码,但我有一个旧的数据库工作。在任何情况下,我算过密码的摘要错误,忘记了to_s方法,使用用户名登录尝试‘希区柯克’和密码‘麦高芬’失败这引起我的测试用例。

现在,看着你的工厂,在我看来,你可能有类似的问题。您迁移文件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字段将是什么?请记住,在运行测试时,首先会清除测试数据库的内容,因此如果您的测试代码未在数据库中创建有效的用户,那么您的登录测试将不起作用。

0

我有这个问题:使用fill_in时填充错误的字段。

的解决办法是遵循文档和使用字符串而不是符号匹配器:

我取代了这一点:

fill_in :email, with: email 
fill_in :password, with: password 

有了:

fill_in "Email", with: email 
fill_in "Password", with: password 

然后它的工作如预期

Docs:https://github.com/jnicklas/capybara#using-capybara-with-rspec