Capybara Database Locked
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!