Mysql 铁路及;RSpec:使用预先存在的记录测试数据库

Mysql 铁路及;RSpec:使用预先存在的记录测试数据库,mysql,ruby-on-rails,ruby,rspec,factory-bot,Mysql,Ruby On Rails,Ruby,Rspec,Factory Bot,我以前的所有项目都使用DatabaseCleaner,所以我习惯于从一个空DB开始,并使用FactoryGirl在每个测试中创建测试数据 目前,我正在从事一个项目,该项目有一个包含许多记录的测试数据库。它是一个sql文件,所有开发人员都必须在其本地测试环境中导入该文件。在持续集成服务器中导入相同的数据库。我觉得对测试数据的控制越少,测试过程就越困难 一些特性允许他们的测试集中在特定的数据上,例如与某个用户关联的记录。在这些情况下,先前存在的数据是不相关的。其他功能(如显示所有客户端项目的报告)不

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

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

一些特性允许他们的测试集中在特定的数据上,例如与某个用户关联的记录。在这些情况下,先前存在的数据是不相关的。其他功能(如显示所有客户端项目的报告)不允许我“忽略”先前存在的数据

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

关于如何应对这种情况,还有其他建议吗


谢谢。

我建议将您的测试数据库和“测试”环境保留为“干净”状态。然后,您可以设置一个单独的数据库,最初将其作为“脏”数据库种子。您的rails\u助手文件中的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文件需要为“脏”数据库添加配置。但我认为这里的关键是保持干净和肮脏的状态分开。干杯

我发现将以下配置添加到
spec/rails\u helper.rb
将在测试内部或(:each)之前以事务的形式运行所有DB操作,这些操作将在每个测试完成后回滚。这意味着我们可以在(:each){MyModel.delete_all}之前执行
之类的操作,创建我们自己的测试数据,运行我们的断言(它只会看到我们创建的数据),在测试结束后,所有先前存在的数据仍将在数据库中,因为删除操作将回滚

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

接触数据库的规格(功能规格)应遵循
arrange-act-assert
模式。此外,数据库应始终以干净/空状态开始。这一点很重要,因为其他测试的遗留问题会导致顺序依赖和奇怪的行为。您可以在每个规范开始时使用一个空数据库,并创建满足您的规范所需的最小记录量,而不是在测试数据库中植入大量数据。然后像使用DBCleaner一样清理规范之间的数据库。@seanriordan08:我同意,您描述了我在以前项目中的工作方式。但是,我在当前项目中没有此选项。这就是为什么我在寻找解决办法。