I've been writing capybara integration tests. It's been going well, until I hit an error.

It happens when I want to update a meeting. It uses capybara with chromedriver. The error message shows:

$SQLite3::BusyException: database is locked: 
commit transaction

The error happens when these lines are executed:

 fill_in 'trest', with: 'canton cooks'
 assert page.has_field?('trest', :with=>'canton cooks')
 click_button('Add restaurant')
 assert_equal  page.evaluate_script('document.getElementById
("addedrest").value'), 'canton cooks'
 click_button('Update Meeting')
 assert_equal current_path, meeting_path(@meeting)

After a few tries to isolate the problem, it turns out that

 setup do
    @meeting = meetings(:one)
    @user = users(:two)
 end

But in order to test edit meeting, we need to have the setup. We have to find ways to fix that. After a few digging online, I came upon this SO answer. Apparently, it's because the server is locking the database so that the test cannot clean up after it has run.

First we tried the suggestion of database_clean option. Have it in gem list and then based on the docs, use these lines:

require 'database_cleaner'

DatabaseCleaner.strategy = :transaction
teardown do DatabaseCleaner.clean end

Run, rake test.......
Nope, it doesn't solve the problem. We ended up the same error message.

The reason after we dug a little further is that it has to use truncation strategy not transaction. But truncation only supports MySql and Postgres and we're using SQLLite. Well, let's read Capybara readme and see whether we could find anything there.

It says, it's also possible to force your ORM to use the same transaction for all threads. This may have thread safety implications and could cause strange failures. It can be implemented in ActiveRecord through the following monkey path:

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

  def self.connection
    @@shared_connection || retrieve_connection
  end
end
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection

Put that into the test_helper file, it worked!