-->

钩原因后为什么加入“睡眠1”在此Rspec的/水豚测试通过?钩原因后为什么加入“睡眠1”在此Rspe

2019-05-12 09:29发布

我使用的铁轨4.0.5,rspec的2.14.1,2.2.1水豚,水豚,WebKit的1.1.0和1.2.0 database_cleaner。 我看到具有以下功能测试一些怪异的行为(它模拟观看一则讯息的评论的用户,鼠标悬停在图标使菜单出现,点击菜单项删除评论):

let(:user){create(:user)}
let(:post){create(:post, author: user)}
let!(:comment){create(:comment, post: post, author: user)}

...

it "can delete a comment" do
  assert(page.has_css? "#comment-#{comment.id}")
  find("#comment-#{comment.id}-controls").trigger(:mouseover)
  find("#comment-#{comment.id} .comment-delete a").click
  assert(page.has_no_css? "#comment-#{comment.id}")
end

这个测试失败时约80%,总是由于某些记录从数据库中被检索nil -我得到NoMethodError: undefined method X for nil:NilClass ,为X的各种值有时无的是,属该评论删除的,有时它是评论的附着后,有时它的意见/帖子的作者。

如果我想补充sleep 1至测试结束,它通过:

it "can delete its own comment" do
  assert(page.has_css? "#comment-#{comment.id}")
  find("#comment-#{comment.id}-controls").trigger(:mouseover)
  find("#comment-#{comment.id} .comment-delete a").click
  assert(page.has_no_css? "#comment-#{comment.id}")
  sleep 1
end

它还传递,如果我把sleep 1中的after块。

任何想法,为什么我得到这些NoMethodErrors,和/或为什么测试通过,如果我让它睡了第二所有的工作完成后?

Answer 1:

我怀疑它可能在你的应用程序的意见,从页面中消失(这是你认定的最后一件事),然后再将其从数据库中删除。 这意味着,该测试可以清理删除之前发生。 如果是这样的话,你可以通过等待实际删除,以在测试结束时发生的修复。 我有解决此方法(的重新实现一个从水豚2中取出但方法仍然有时需要 )

def wait_until(delay = 1)
  seconds_waited = 0
  while ! yield && seconds_waited < Capybara.default_wait_time
    sleep delay
    seconds_waited += 1
  end
  raise "Waited for #{Capybara.default_wait_time} seconds but condition did not become true" unless yield
end

所以我可以做

wait_until { Comment.count == 0 }

在测试中。

另一种方法是增加机架中间件块的请求测试结束后作出的。 这种方法在这里详细描述: http://www.salsify.com/blog/tearing-capybara-ajax-tests我看见它做一个良好的中小型浴室的RSpec功能规格的解决数据泄露的一份很好的工作。



Answer 2:

https://github.com/jnicklas/capybara#asynchronous-javascript-ajax-and-friends

当异步JavaScript的工作,你可能会遇到,你正试图与尚未出现在页面上的元素进行交互的情况。 水豚自动等待元素出现在页面上与此交易。



文章来源: Why does adding “sleep 1” in an after hook cause this Rspec/Capybara test to pass?