水豚错误ActiveRecord :: StatementInvalid:SQLite3 :: BusyException:数据库已锁定

问题描述:

我正在测试javascript,尝试通过ajax表单向数据库提交数据时出现以下错误。

I'm testing javascript and I get the following error when I try and submit data to the DB over an ajax form.

ActiveRecord::StatementInvalid:         ActiveRecord::StatementInvalid: SQLite3::BusyException: database is locked: INSERT INTO "check_category_item_keys" ("name", "key_type", "created_at", "updated_at") VALUES (?, ?, ?, ?)

这是我的集成测试文件

require 'test_helper'

class JavascriptTestingTest < ActionDispatch::IntegrationTest

setup do
    @user = users(:michael)
    @user1 = users(:archer)
    @guide = Guide.find(1)
    @mod_relationship = game_mods_relationships(:mod1)
    @category = Category.find(1)
    Capybara.current_driver = Capybara.javascript_driver # :selenium by default
  end


test "adding keys mod success then fail" do
  log_in_as(@user)
  visit(edit_guide_category_path(@guide, @category))
  itemkeycount = CategoryItemKey.count
  fill_in 'Key name', with: "diablo"
  click_button "Add New Key"  #works fine when this line is removed
end

我是测试JS的新手,所以我猜想还有更多事情要做或需要更改。

I'm new to testing JS so I'm guessing there is something more I need to do or something I need to change.

#click_button 并不等待单击按钮的结果发生,因为它不知道那会是什么。因此,在这种情况下, #click_button 立即返回,测试结束,并且您在两次测试之间用来清理数据库的任何内容(DatabaseCleaner ??)都会开始清理数据库。在这段时间内,由click_button触发的请求开始得到处理,但是清理线程已经锁定了数据库(或者反过来),因此您会收到错误消息。解决方案是让一行等待任何单击按钮的可见副作用。

#click_button does not wait for the results of clicking the button to happen since it has no clue what those will be. So in this case #click_button returns immediately, the test ends, and whatever you're using to clean the database between tests (DatabaseCleaner??) starts cleaning the database. During that time the request triggered by click_button starts to get processed but the cleaning thread has already locked the database (or the other way around) so you get an error. The solution is to have a line that waits for a visible side effect of whatever clicking the button does.

fill_in 'Key name', with: "diablo"
click_button "Add New Key"
assert_text "New Key Added!" # or whatever shows up the page

assert_text将等待(最大限制)该文本出现,这意味着数据库已不再使用,测试可以完成并且可以进行清理。要注意的另一件事是,您不使用基于事务的测试,因为在使用具有JS功能的驱动程序进行测试时,这还会引起各种问题-请参见 https://github.com/DatabaseCleaner/database_cleaner#what-strategy-is-fastest

The assert_text will wait (up to a limit) for that text to appear which should mean the database is no longer in use, the test can finish and cleanup can happen. The other thing to watch for is that you're NOT using transaction based testing since that will also cause you all sorts of issues when doing testing with a JS capable driver - see https://github.com/DatabaseCleaner/database_cleaner#what-strategy-is-fastest