简体   繁体   中英

Capybara and chrome driver: SQLite3::BusyException: database is locked

Once in a while I use chromedriver when running my feature specs to do some visual testing etc. For this, I simply set driver: :chrome on the specific spec.

I didn't do this for a long time it seems, as since I tried it today, I got the following error:

SQLite3::BusyException: database is locked

This doesn't happen when running the specs using the default JavaScript driver (which is poltergeist).

A search on Google lead to this solution which shows how to monkey patch active record . Still, this feels odd to me. Why did it work before? Is it some threading issue? I don't like monkey patching, maybe there's a better solution for this.

According to this feature in cucumber-rails:

When running a scenario with the @javascript tag, Capybara will fire up a web server in the same process in a separate thread to your cukes. By default, this means ActiveRecord will give it a separate database connection, which in turn means data you put into your database from Cucumber step definitions (eg using FactoryGirl) won't be visible to the web server until the database transaction is committed.

So if you use a transaction strategy for cleaning up your database at the end of a scenario, it won't work for javascript scenarios by default.

There are two ways around this. One is to switch to a truncation strategy for javascript scenarios. This is slower, but more reliable.

The alternative is to patch ActiveRecord to share a single database connection between threads. This means you still get the speed benefits of using a transaction to roll back your database, but you run the risk of the two threads stomping on one another as they talk to the database.

Right now, the default behavior is to use truncation, but you can override this by telling cucumber-rails which strategy to use for javascript scenarios.

The deletion strategy can be quicker for situations where truncation causes locks which has been reported by some Oracle users.

From the last paragraph, you could use the deletion strategy by changing the following line in env.rb :

Cucumber::Rails::Database.javascript_strategy = :truncation

by:

Cucumber::Rails::Database.javascript_strategy = :deletion

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM