Why not use shared ActiveRecord connections for Rspec + Selenium?

It seems that the most common way to deal with Selenium and tests is to avoid using transactional devices, and then using something like database_cleaner between tests / scripts. Recently, I came across 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 more loaded for performance than alternatives. Does anyone have a reason why this should not be used?

+45
ruby ruby-on-rails rspec capybara
Jan 08 2018-12-01T00:
source share
6 answers

This decision was written by Jose Valim, a highly respected Rails community and a member of the core Rails team. I doubt that he would recommend using it if there were problems with it. I personally had no problems.

Just keep in mind that if you use Spork, it must be in each_run block to work.

FWIW. I had problems with intermittent release of capybara with the above patch on Postgres. Mike Perham's solution, which @hsgubert below seems to solve these problems. Now I am using this solution.

+17
Jan 08 2018-12-12T00:
source share
— -

Actually there is a problem with it. For example, if you use gem mysql2, you will see some errors, for example:

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

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

 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 will also need to set gem connection_pool . This will save you a lot of headaches.

+33
Aug 23 2018-12-12T00:
source share

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 is reported to lead to non-deterministic failures.

+2
Jul 12 '14 at 12:48
source share

I ran into a problem using the code mentioned in my spec_helper.rb file.

What happens when your tests depend on using connections to multiple databases? I have two databases that I need to connect to when I run my tests. I did a simple test to check what happens to the database connections that I install.

 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. puts "First Record cxn: #{FirstDatabase::Record.connection}" # => First Record cxn: #<ActiveRecord::ConnectionAdapters::Mysql2Adapter:0xe59b524> puts "AR Base cxn: #{ActiveRecord::Base.connection}" # => AR Base cxn: #<ActiveRecord::ConnectionAdapters::Mysql2Adapter:0xc52761c> ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection puts "First Record cxn: #{FirstDatabase::Record.connection}" # => First Record cxn: #<ActiveRecord::ConnectionAdapters::Mysql2Adapter:0xc52761c> puts "AR Base cxn: #{ActiveRecord::Base.connection}" # => AR Base cxn: #<ActiveRecord::ConnectionAdapters::Mysql2Adapter:0xc52761c> 

As you can see, before I call the shared connection method, I have two different database connections. After calling the general connection method, I have only one.

Thus, any test that requires a transition to the second database connection to retrieve information will fail.: (

I am going to post this problem and see if anyone has come to a solution.

+1
Jul 26 '13 at 18:50
source share

I just read a little about it. I found a snippet that you shared here in this blog post:

http://blog.plataformatec.com.br/2011/12/three-tips-to-improve-the-performance-of-your-test-suite/

To answer your question directly, the Database Cleanup Vigilance page warns that it can "lead to non-deterministic crashes." I would go straight ahead and use it, but if you start to encounter strange setbacks, maybe this is a good place to start looking.

+1
Aug 04 '13 at 23:33
source share

There is a good thing at the end of this post. This may explain why I get a MALLOC error when I try a very simple thread script.

http://apidock.com/rails/ActiveRecord/Base/connection

 leente - March 15, 2011 0 thanks Don't cache it! Don't store a connection in a variable, because another thread might try to use it when it's already checked back in into the connection pool. See: ActiveRecord::ConnectionAdapters::ConnectionPool connection = ActiveRecord::Base.connection threads = (1..100).map do Thread.new do begin 10.times do connection.execute("SELECT SLEEP(1)") # WRONG ActiveRecord::Base.connection.execute("SELECT SLEEP(1)") # CORRECT end puts "success" rescue => e puts e.message end end end threads.each(&:join) 
+1
Dec 04 '13 at 0:47
source share



All Articles