使用 Rspec + Capybara + Ember 获得不一致的"Unable to find css"错误



近况

在我们的Rspec + Capybara + selenium (FF)测试套件中,我们得到了许多不一致的"Capybara::ElementNotFound"错误。

问题是它们只是偶尔发生。通常它们不会在本地发生,它们会发生在CircleCi上,我希望那里的机器更强大(所以更快)?

同样的错误通常不会在单独运行规范时发生,例如运行带有特定行号的rspec:42。

但是请记住,没有一致性。规范不会总是失败。

我们当前的解决方法-睡眠

目前我们唯一能做的就是用'睡眠'乱扔规格。每当我们遇到这样的错误时,我们就把它们加起来,它就会修复它。有时我们不得不增加睡眠时间,这使得测试非常慢,你可以想象。

水豚的默认等待时间是多少?

似乎没有启动,我想测试通常在分配的等待时间(目前为5秒)下失败

一些失败的例子

下面是一个常见的错误:

visit "/#/things/#{@thing.id}"
find(".expand-thing").click

这通常会导致:

Unable to find css ".expand-thing"

现在,在这两行之间放一个sleep来修复它。但是睡觉太残忍了。我可能会加一秒,但代码可能只需要半秒。

理想情况下,我希望水豚的等待时间开始,因为这样它只等待它需要的时间,而不是更长。

<标题>

我知道capybara只能做等待的事情,如果选择器还不存在的页面上。但是在上面的例子中,你会注意到我正在访问页面和选择,所以元素还没有在页面上,所以Capybara应该等待。

怎么回事?

我明白了。因此,当您在页面上查找元素时,您可以使用以下几种方法:

first('.some-selector')
all('.some-selector') #returns an array of course
find('.some-selector')

.first.all非常有用,因为它们可以让您从非唯一元素中进行选择。

然而,.first.all似乎不会自动等待元素出现在页面上。

修复

解决方法是始终使用.find().find将尊重水豚的等待时间。使用.find几乎完全修复了我的测试(除了一些不相关的异常)。

gotcha当然是你必须使用更多的唯一选择器作为.find必须只返回一个元素,否则你会得到臭名昭著的Capybara::Ambiguous异常。

Ember异步工作。这就是Ember通常推荐使用Qunit的原因。他们在代码中绑定了允许在等待异步函数返回时暂停/恢复测试的代码。最好的办法是尝试复制为qunit构建的暂停/恢复逻辑,或者切换到qunit。

在测试过程中有一个全局承诺,你可以连接到:Ember.Test.lastPromise

Ember.Test.lastPromise.then(function(){
  //continue
});

另外,访问/点击返回承诺,你需要以某种方式告诉capybara在调用之前暂停测试,然后在承诺恢复后继续。

visit('foo').then(function(){
  click('.expand-thing').then(function(){
    assert('foobar');
  })
})

现在我已经完成了演讲,我意识到从技术上讲,您不是在浏览器内部运行这些测试,而是让它们通过selenium运行,这意味着从技术上讲,它不是在浏览器中运行的(除非selenium在我上次使用它之后做了一些更改,这是可能的)。无论哪种方式,您都需要关注最后一个承诺,并在继续之前等待它,在异步操作之后进行测试。

相关内容

最新更新