2

我最近将 mi CI 服务器(Teamcity)移到了另一台具有相同配置和非常相似操作系统的强大机器上。

从那以后,我的一些集成规范开始失败。我的设置非常标准,Rails 3 + capybara + poltergeist + phantomjs。

失败是确定性的,它们总是会发生,并且总是与 DOM 中一些缺失的节点有关。此外,故障发生在具有相似设置的不同项目中,因此与项目配置无关。capybara 1.x 和 capybara 2 都会发生这种情况。

这是最简单的失败规范。请注意,此规范无需 javascript 即可运行,因此该问题也存在于仅机架规范中。

scenario 'require an unsubscription' do
  visit unsubscribe_index_path
  within main_content do
    choose list.description
    fill_in 'Email', :with => subscriber.email
    click_button 'Unsubscribe'
  end
  save_page # <--- Added to debug output
  # !!! HERE is the first failing assertion
  page.should have_content('You should have received a confirmation message')
  # Analytics event recorded
  # !!! this also is failing
  page.should have_event('Unsubscription', 'Sent', list_name)
  # If I comment previous two lines the spec passes on CI machine
  # this means that the form is submitted with success since email is triggered
  # from controller code
  last_email_sent.should have_subject 'Unsubscribe request received'
  last_email_sent.should deliver_to subscriber.email
end

我试过的:

  • 在不同的机器上运行规范,它们可以在每台开发机器上运行,也可以在登台服务器上运行。即使在 CI 环境之外,我也只能在 CI 机器上重现故障(即通过命令行运行规范)
  • 增加到Capybara.default_wait_time一个荒谬的20
  • 尝试在上page.should have_content线前进行残酷的睡眠
  • 在 CI 机器上升级 RVM、ruby、capybara、poltergeist 的最新版本。
  • 将teamcity升级到最新版本

我发现的最奇怪的事情是当我save_page在失败行之前添加了一个调用。如果我在我的机器上运行规范,然后在服务器出现故障的 CI 上运行并比较这两个文件,结果是这样的:

$ diff capybara-201309071*.html
26a27,29
> <script type='text/javascript'>
> _gaq.push(["_trackEvent","Unsubscription","Sent","listname"]);
> </script>
90a94,96
>             <div class="alert-message message notice">
>               <p>You should have received a confirmation message</p>
>             </div>

这是导致规范失败的两个缺失部分,因此提交了表单,控制器操作成功运行,但缺少两个 dom。这怎么可能?为什么这只发生在一台机器上?

作为记录,这两个 DOM 是使用标准 rails 工具添加的,其中一个是

redirect_to unsubscribe_index_path, notice: ...

另一个是分析宝石

4

1 回答 1

0

我发现了这个问题,我使用 dalli_store 作为会话存储的两个失败项目,我把config.cache_store = :dalli_store线放在config/application.rb而不是config/environments/production.rb.

在旧的 CI 服务器上,有一个 memcached 守护进程正在运行,因此所有规范都运行良好。

在新服务器中,因为它只是一个 CI 服务器,并且它不运行任何生产或暂存代码 memcached 不存在,因此任何会话写入(例如闪存消息)都被静默丢弃,这就是所有此类规范的原因失败。

我通过将该config.cache行放入适当的环境文件来解决,但我仍然想知道为什么 dalli gem 在没有可用的 memcached 时不会发出任何警告。虽然选择在缺少缓存守护程序时不失败是合理的,因为应用程序应该在没有缓存数据的情况下工作,但它可能是生产代码中的性能杀手,如果没有给出警告,它可能会被忽视。

于 2013-09-09T11:30:16.667 回答