Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not use shared ActiveRecord connections for Rspec + Selenium?

It seems the most commonly accepted way to deal with Selenium and tests is to avoid using transactional fixtures and then using something like database_cleaner between tests/scenarios. I recently ran into the following article which suggested doing the following:

spec_helper.rb

class ActiveRecord::Base
  mattr_accessor :shared_connection
  @@shared_connection = nil

  def self.connection
    @@shared_connection || retrieve_connection
  end
end

# Forces all threads to share the same connection. This works on
# Capybara because it starts the web server in a thread.
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection

This seems loads better for performance than the alternatives. Does anyone have any reason why this shouldn't be used?

like image 607
Ryan Avatar asked Jan 08 '12 00:01

Ryan


3 Answers

Actually there are issues with it. If you use the gem mysql2, for example, you'll start seeing some errors like:

Mysql2::Error This connection is still waiting for a result

Please use this instead. It was written by Mike Perham, all credits to him.

class ActiveRecord::Base
  mattr_accessor :shared_connection
  @@shared_connection = nil

  def self.connection
    @@shared_connection || ConnectionPool::Wrapper.new(:size => 1) { retrieve_connection }
  end
end

ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection

You'll need to install gem connection_pool too. This will spare you from many headaches.

like image 130
hsgubert Avatar answered Oct 20 '22 07:10

hsgubert


This solution was written by Jose Valim - well respected in the Rails community and a member of the Rails core team. I doubt he would recommend using it if there were issues with it. I personally haven't had any issues.

Just be aware that if you use Spork this needs to be in the each_run block to work.

FWIW - I have had intermittent capybara test issues with the above patch on Postgres. The Mike Perham solution that @hsgubert has below appears to have solved those issues. I am now use that solution.

like image 15
nmott Avatar answered Oct 20 '22 06:10

nmott


The DatabaseCleaner gem readme answers your "why not" question this way:

One common approach is to force all processes to use the same database connection (common ActiveRecord hack) however this approach has been reported to result in non-deterministic failures.

like image 2
Arcolye Avatar answered Oct 20 '22 08:10

Arcolye