我的 RSpec 请求规范中对 sleep 的调用有效吗?

发布于 2024-12-07 13:06:51 字数 2902 浏览 0 评论 0原文

我单击“显示并销毁”与 Capybara 的链接,该链接应位于员工表的第一个表行中。该表应根据 update_at 时间戳进行排序,以便最近修改的员工位于顶部。

在该示例之前,必须创建一个通过身份验证的有效员工。然后在示例开始时必须创建一个员工来进行测试。 这个是应该始终位于表顶部的员工,因为它应该是最近修改过的。有时是,有时不是。添加睡眠呼叫可以解决此问题,我想知道这是否有效或者我是否弄错了。我认为在测试中添加睡眠呼叫是一件坏事。我还认为,如果身份验证员工是在示例之前创建的,那么即使我的规范运行得非常快,那么它仍然应该具有较早的 update_at 时间戳。

身份验证宏:

module AuthenticationMacros
  def login_confirmed_employee
    # create a valid employee for access
    Factory :devise_confirmed_employee,
      :username => 'confirmed.employee',
      :password => 'password',
      :password_confirmation =>'password'

    # sign in with valid credentials
    visit '/employees/sign_in'
    fill_in 'Username', :with => 'confirmed.employee'
    fill_in 'Password', :with => 'password'
    click_on 'Sign In'
  end
end

有问题的请求规范:

require 'spec_helper'
include AuthenticationMacros

describe "Employees" do

  before do
    login_confirmed_employee
  end

  # shows employees
  it "shows employees" do
    sleep 1.seconds
    Factory :employee_with_all_attributes,
      :username => 'valid.employee',
      :email => '[email protected]',

    visit '/employees'
    within 'tbody tr:first-child td:last-child' do; click_on 'Show', end
    page.should have_content 'valid.employee'
    page.should have_content '[email protected]'
  end


  # destroys employees
  it "destroys employees" do
    sleep 1.seconds
    Factory(:employee)
    visit '/employees'
    within 'tbody tr:first-child td:last-child' do; click_on 'Delete', end
    page.should have_content 'Employee was successfully deleted.'
  end
end 

并且为了更好地衡量,这是我的spec_helper:

require 'spork'

Spork.prefork do

  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
  ActiveSupport::Dependencies.clear
  require 'email_spec'
  RSpec.configure do |config|
    config.include EmailSpec::Helpers
    config.include EmailSpec::Matchers
  end
end

Spork.each_run do
  require 'rspec/rails'
  require 'factory_girl_rails'
  require 'capybara/rspec'
  require 'capybara/rails'
  require 'shoulda'

  RSpec.configure do |config|

    config.mock_with :rspec
    config.use_transactional_fixtures = false

    config.before(:suite) do
      DatabaseCleaner.strategy = :truncation
    end

    config.before(:each) do
      DatabaseCleaner.start
    end

    config.after(:each) do
      DatabaseCleaner.clean
    end
  end
end

有时我最终会出现在显示页面上或销毁需要身份验证的员工而不是示例员工。但如果我添加 1 秒睡眠,则永远不会发生这种情况称呼。

I'm clicking show and destroy links with Capybara that should be in the first table row in an employees table. The table should sort so that the most recently modified employee is on the top, based on the updated_at timestamp.

Before the example a valid employee must be created that passes authentication. Then at the beginning of the example an employee must be created to test with. This is the employee that should always be at the top of the table because it's supposed to have been modified most recently. Sometimes it is and sometimes it isn't. Adding a sleep call fixes this, and I'm wondering if that's valid or if I've got it wrong. I thought adding a sleep call in a test was a Bad Thing. I also thought if the authentication employee is created before the example then even if my spec is running really fast then it should still have an earlier updated_at timestamp.

The authentication macro:

module AuthenticationMacros
  def login_confirmed_employee
    # create a valid employee for access
    Factory :devise_confirmed_employee,
      :username => 'confirmed.employee',
      :password => 'password',
      :password_confirmation =>'password'

    # sign in with valid credentials
    visit '/employees/sign_in'
    fill_in 'Username', :with => 'confirmed.employee'
    fill_in 'Password', :with => 'password'
    click_on 'Sign In'
  end
end

The request spec in question:

require 'spec_helper'
include AuthenticationMacros

describe "Employees" do

  before do
    login_confirmed_employee
  end

  # shows employees
  it "shows employees" do
    sleep 1.seconds
    Factory :employee_with_all_attributes,
      :username => 'valid.employee',
      :email => '[email protected]',

    visit '/employees'
    within 'tbody tr:first-child td:last-child' do; click_on 'Show', end
    page.should have_content 'valid.employee'
    page.should have_content '[email protected]'
  end


  # destroys employees
  it "destroys employees" do
    sleep 1.seconds
    Factory(:employee)
    visit '/employees'
    within 'tbody tr:first-child td:last-child' do; click_on 'Delete', end
    page.should have_content 'Employee was successfully deleted.'
  end
end 

And for good measure here's my spec_helper:

require 'spork'

Spork.prefork do

  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
  ActiveSupport::Dependencies.clear
  require 'email_spec'
  RSpec.configure do |config|
    config.include EmailSpec::Helpers
    config.include EmailSpec::Matchers
  end
end

Spork.each_run do
  require 'rspec/rails'
  require 'factory_girl_rails'
  require 'capybara/rspec'
  require 'capybara/rails'
  require 'shoulda'

  RSpec.configure do |config|

    config.mock_with :rspec
    config.use_transactional_fixtures = false

    config.before(:suite) do
      DatabaseCleaner.strategy = :truncation
    end

    config.before(:each) do
      DatabaseCleaner.start
    end

    config.after(:each) do
      DatabaseCleaner.clean
    end
  end
end

Sometimes I end up on the show page or destroying the authentication-required employee instead of the example employee.It never happens though if I add the 1 second sleep call.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情魔剑神 2024-12-14 13:06:51

不,事实上这是一个非常糟糕的解决方案,因为它增加了测试执行时间。
您可以使用以下解决方案之一模拟 Time.now 方法调用:

Nope, it fact it's a very bad solution because it increases tests execution time.
You could mock Time.now method call using one of the following solutions:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文