Rails:如何在我的 Capybara 集成测试中测试秒表?

Rails: how can I test a stopwatch in my Capybara integration tests?

目前正在为我的 Rails 应用程序的时间跟踪功能编写测试。我想不出一种方法来模拟单击计时器上的 "play" 按钮,等待几秒钟,单击暂停然后提交表单(创建一个新的 Timestamp 对象)。

test "track time with stopwatch" do
    visit new_project_timestamp_path(@project)
    find('#play_button').click 
    sleep 4.0
    find('#pause_button').click
    click_button "submit_new_timestamp"
    visit project_path(@project)
    assert page.has_content? "4 seconds"
 end

^这是我想要它做的事情的要点,但是 sleep 显然不起作用,因为它完全挂起线程,而我希望测试有点 "wait around" 而秒表正在执行它几秒钟。上面的测试失败了,因为没有实际跟踪时间;暂停在播放后立即单击,在计时器的眼中,因此提交表单时没有记录实际时间,这当然会引发验证错误。

有没有一种方法可以模拟等待几秒钟而不实际挂起线程?

假设您使用的是支持 JS 的驱动程序(selenium、poltergeist、capybara-webkit),然后浏览器、正在测试的应用程序,并在自己的 threads/processes 中测试所有 运行,所以睡觉在你的测试线程中应该完全没问题。与其在没有时间差异的情况下提交两次点击,更有可能是您的 click_button 被紧随其后的 visit 取消,因此您没有创建新的时间戳。您需要断言 'click_button` 和 'visit' 之间的某种可见变化,以确保在告诉浏览器请求新页面

之前创建新的时间戳操作已完成
click_button "submit_new_timestamp"
page.assert_text "Timestamp created" # whatever message/visible change occurs after clicking the button
visit project_path(@project)

此外,使用 assert_text、assert_selector、assert_title、assert_current_path 匹配器会在断言失败时为您提供比断言 has_xxx? 方法

(注意:非常感谢 Tom Walpole 的回答。问题是我没有使用支持 JS 的 Web 驱动程序。以为我会为其他因同样缺乏而遇到类似问题的人写这篇文章我有理解。)

问题是我没有使用执行 Javascript 的网络驱动程序。默认情况下,Capybara 使用 :rack_test 驱动程序,虽然速度很快,但不会执行 Javascript.

因此对于依赖于执行 JS 的集成测试(在我的例子中是与秒表交互),像 :poltergeist 这样的东西是个好主意。要设置它,请添加

  gem 'poltergeist'
  gem 'phantomjs', :require => 'phantomjs/poltergeist'

到 Gemfile 和 运行 bundle install.

您需要添加

  require 'capybara/poltergeist'
  Capybara.javascript_driver = :poltergeist

到您的 test/spec 帮助程序文件。然后,您需要做的就是在需要支持 JS 的集成测试的任何地方设置 Capybara.current_driver = Capybara.javascript_driver