2

我很难调查测试失败的原因。我是一位非常有经验的程序员,并且精通一般调试技术,但我对 Capybara 和 RSpec 不熟悉,所以我希望有某种我不知道的工具可以帮助我。

简而言之,我有一个类似这样的测试:

expect { click('.fake_button'); sleep 1 }.to change { clicks.count }.by(1)

当点击假按钮时,它会触发对 Rails 应用程序的 AJAX 调用,其中包括向数据库添加点击记录。我能想到许多可能导致此测试失败的事情,并且从日志中获取信息的成功有限。测试在开发中不会失败,只是偶尔会在测试中失败。测试环境的差异之一是测试是在我们办公室的服务器上针对云中的服务器运行的,因此存在网络延迟以及其他可能的问题。

这很难诊断,因为从失败的测试中得到的信息太少了,当然,当我读到有关失败的信息时,所有的数据库信息都被丢弃了。我知道clicks.count测试中没有改变,我可以推断click('.fake_button')成功,但由于服务器时间同步问题,我什至不能确定单击发生在右侧按钮上或 AJAX 调用是否已触发。

我想要一些工具来帮助我在 web 服务器日志中跟踪这个测试用例(例如,可能使用自动 URL 参数)、关于 Capybara 所做的详细日志记录以及网页记录发生故障,包括 cookie 值。我能得到这些吗?有这样的吗?

4

3 回答 3

3

Capybara 模拟人类行为。测试代码完全符合需要。这是真正的用户应该期待的。我认为你不应该抱怨代码。

我认为可以增加等待时间,比如 1 到 2,因为您的网络延迟,但它不应该超过一个合理的值,否则应用程序不能像真实用户预期的那样工作。

调试 Capybara 代码,我总结了三种方法:

  1. 将“save_and_open_page”添加到您想要查看结果的位置。然后在测试过程中会出现一个保存的html页面。(我忘记是否应该添加“启动”宝石)

  2. 暂时把这个测试设置成JS,看看这个测试怎么样。

    scenario "a fake test", js: true do
      # code here
    end
    

    这样做会弹出一个真正的浏览器,Capybara 会逐步向您展示它是如何播放代码的。

  3. 只需运行$ tail log/test.log以显示最近发生的事情。

于 2013-03-27T07:22:42.323 回答
1

以@Billy 的建议为基础,log/test.log并没有给我任何有用的信息,而且我已经在使用js: true,所以我尝试了这个:

begin
  expect { click('.fake_button'); sleep 1 }.to change { clicks.count }.by(1)
rescue Exception => e
  begin
    timestamp = Time::now.strftime('%Y%m%d%H%M%S%L')
    begin
      screenshot_name = "tmp/capybara/capybara-screenshot-#{timestamp}.png"
      $stderr.puts "Trying to save screenshot #{screenshot_name} due to test failure"
      page.save_screenshot(screenshot_name)
    rescue Exception => inner
      $stderr.puts "Ignoring exception #{inner} while trying to save screenshot of test page"
    end
    begin
      # Page saved by Capybara under tmp/capybara/ by default
      save_page "capybara-html-#{timestamp}.html"
    rescue Exception => inner
      $stderr.puts "Ignoring exception #{inner} while trying to save HTML of failed test page"
    end
  ensure
    raise e
  end
end

后来我通过执行以下操作更改了测试本身以利用 Capybara 的 AJAX 同步功能:

    starting_count = clicks.count
    click('.fake_button')
    page.should have_css('.submitted')     # Capybara is smart enough to wait for this to happen
    clicks.count.should == starting_count + 1

请注意,我正在寻找的 CSS 是通过 AJAX 回调在 JavaScript 中添加到页面的内容,因此它的显示是 AJAX 调用完成的信号。

这些rescue块很重要,因为屏幕截图的失败率很高,因为没有足够的内存来呈现整个页面并将其转换为图像。

编辑

虽然我还没有尝试过,但有希望的解决方案是Capybara::Screenshot,它会在任何失败时自动保存屏幕截图和 HTML。只是阅读代码,当屏幕截图失败时它看起来会出现问题,并且我无法判断屏幕截图被触发时页面将处于什么状态,但它看起来确实值得一试。

于 2013-03-29T22:12:30.937 回答
0

调试测试的一个好方法是使用 irb 来观察浏览器中实际发生的情况。RSpec 失败通常会为简单的案例提供不错的信息,但对于更复杂的事情,我要么将案例拆分直到它变得简单,要么将其放入 irb 进行实时会话,以确保它完成它应该做的事情。

确保使用 :selenium 作为您的驱动程序,您应该会看到 firefox 出现并且能够被您的 irb 会话驱动。

于 2013-03-28T00:13:54.620 回答