【问题标题】:Capybara and chrome driver: SQLite3::BusyException: database is lockedCapybara 和 chrome 驱动程序:SQLite3::BusyException: 数据库被锁定
【发布时间】:2015-06-05 21:10:03
【问题描述】:
有时我会在运行我的功能规范时使用 chromedriver 进行一些视觉测试等。为此,我只需在特定规范上设置 driver: :chrome。
我好像很久没做这个了,因为我今天试了一下,出现如下错误:
SQLite3::BusyException: database is locked
使用默认 JavaScript 驱动程序(即 poltergeist)运行规范时不会发生这种情况。
在 Google 上的搜索导致此solution which shows how to monkey patch active record。不过,这让我感觉很奇怪。为什么之前有效?是线程问题吗?我不喜欢猴子补丁,也许有更好的解决方案。
【问题讨论】:
标签:
ruby-on-rails
rspec
sqlite
【解决方案1】:
根据 cucumber-rails 中的this 功能:
当运行带有@javascript 标签的场景时,Capybara 将触发
在一个单独的线程中的同一进程中启动一个 Web 服务器到您的
杯子。默认情况下,这意味着 ActiveRecord 会给它一个单独的
数据库连接,这反过来意味着您放入您的数据
来自 Cucumber 步骤定义的数据库(例如使用 FactoryGirl)不会
在数据库事务完成之前对 Web 服务器可见
承诺。
因此,如果您使用事务策略清理数据库
一个场景的结束,它不适用于 javascript 场景
默认。
有两种方法可以解决这个问题。一种是切换到截断
javascript场景的策略。这速度较慢,但更可靠。
另一种方法是修补 ActiveRecord 以共享单个数据库
线程之间的连接。这意味着您仍然可以获得速度
使用事务回滚数据库的好处,但是您
冒着两个线程在说话时相互踩踏的风险
到数据库。
目前,默认行为是使用截断,但您可以
通过告诉 cucumber-rails 使用哪种策略来覆盖它
JavaScript 场景。
对于截断的情况,删除策略可以更快
导致一些 Oracle 用户报告的锁。
从最后一段开始,您可以通过更改env.rb 中的以下行来使用删除策略:
Cucumber::Rails::Database.javascript_strategy = :truncation
作者:
Cucumber::Rails::Database.javascript_strategy = :deletion