Rails& RSpec:测试具有预先存在记录的数据库

时间:2017-09-21 21:33:38

标签: mysql ruby-on-rails ruby rspec factory-bot

我之前的所有项目都使用了DatabaseCleaner,所以我习惯于从空数据库开始,并使用FactoryGirl在每个测试中创建测试数据。

目前,我正在开发一个具有许多记录的测试数据库的项目。它是sql文件,所有开发人员必须在其本地测试环境中导入。在持续集成服务器中导入相同的DB。我觉得对测试数据的控制较少会使测试过程更加困难。

某些功能允许他们的测试专注于特定数据,例如与特定用户关联的记录。在这些情况下,预先存在的数据是无关紧要的。其他功能(如显示所有客户项目的报告)不允许我“忽略”先前存在的数据。

在某些测试中是否有任何方法可以忽略测试数据库内容(模拟空数据库并创建自己的测试数据而不实际删除测试数据库中的所有行)?也许有两个数据库(都在同一个MySQL服务器上)并且能够在它们之间切换(例如,一些测试使用一个DB,其他测试使用另一个DB)?

关于如何处理这种情况的任何其他建议?

谢谢。

2 个答案:

答案 0 :(得分:1)

我建议保留test_database,并将'test'环境保存为“干净”状态。然后,您可以设置一个单独的数据库,您最初将其作为“脏”数据库。您还可以使用以下内容设置rails_helper文件中的before hook:

RSpec.configure do |config|
  config.before :each, type: :feature do |example|
    if ENV['TEST_DIRTY'] || example.metadata[:test_dirty]
      ActiveRecord::Base.establish_connection(
        {
          :adapter => 'mysql2',
          :database => 'test_dirty',
          :host => '127.0.0.1',
          :username => 'root',
          :password => 'password'
        }
      )
    end
  end
end

您的database.yml文件需要为“脏”数据库添加配置。但我认为这里的关键是保持你的清洁和肮脏的状态分开。干杯!

答案 1 :(得分:1)

我发现将以下配置添加到spec/rails_helper.rb将在测试或before(:each)块中运行所有数据库操作作为事务,这些事务在每次测试完成后回滚。这意味着我们可以执行类似before(:each) { MyModel.delete_all }的操作,创建我们自己的测试数据,运行我们的断言(只会看到我们创建的数据),并且在测试结束后,所有预先存在的数据仍然在数据库中,因为删除将被回滚。

RSpec.configure do |config|
  config.use_transactional_fixtures = true
end