如何使用内存数据库运行RailsSystemTest



我为测试环境设置:memory:数据库

test:
adapter: sqlite3
database: ":memory:"

并且在SystemTest设置时始终运行数据库迁移

require "test_helper"
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :firefox, screen_size: [1400, 1400]
setup do
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Schema.verbose = false
load "#{Rails.root.to_s}/db/schema.rb"
end

我调试了一下,发现迁移工作正常。然而,在浏览器启动后,Rails应用程序数据库似乎被重置了,所以测试抛出了错误SQLite3::SQLException: no such table

即使我在下面的测试用例中尝试迁移数据库,由于上述原因,它仍然失败了。

test "visiting the index" do
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Schema.verbose = false
load "#{Rails.root.to_s}/db/schema.rb"
@task = Task.create!(..) # OK

# FAILED
visit tasks_url
assert_selector "h1", text: "Tasks"
end

在正常数据库设置的情况下,它可以正常工作。所以我想当Capybara启动浏览器时,:memory:db会重置。

如何为Rails SystemTest设置:memory:数据库?谢谢

我想出了一个作弊的方法:在Capybara第一次启动浏览器的每个测试用例时迁移:memory:db,为此,我在测试环境中扩展了ApplicationController,就像一样

# test_helper.rb
...
class ApplicationController
before_action :migrate_db
def migrate_db
if in_memory_db?
# each time Capybara `visit` is called
# load and seed db if the :memory: db is reset
begin
task_count = Task.count
rescue => e
load "#{Rails.root}/db/schema.rb"
ensure
# seed memory db
if task_count.nil? || task_count.zero?
Task.create!(...)
end
end
end
end
# copy from https://github.com/rails/rails/blob/main/activerecord/test/cases/helper.rb#L39
private def in_memory_db?
ActiveRecord::ConnectionAdapters.const_defined?(:SQLite3Adapter) &&
ActiveRecord::Base.connection.is_a?(ActiveRecord::ConnectionAdapters.const_get(:SQLite3Adapter)) &&
ActiveRecord::Base.connection_pool.db_config.database == ":memory:"
end
end

最新更新