Blastula
Blastula

Reputation: 504

Is this call to sleep in my RSpec request spec valid?

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.

Upvotes: 3

Views: 5963

Answers (1)

luacassus
luacassus

Reputation: 6720

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:

Upvotes: 3

Related Questions