阻止Rails测试删除种子数据

时间:2009-12-14 03:40:11

标签: ruby-on-rails ruby testing fixtures seed

我正在使用seeds.rb来填充一些州模型参考数据:

State.create :name => 'Alabama', :abbreviation => 'AL'
State.create :name => 'Alaska', :abbreviation => 'AK'
# ...

虽然我没有使用状态固定装置(因为它的种子数据一开始,我认为仅仅为了测试而不得不复制它),Rails测试框架似乎在删除所有状态种子数据期间测试。 (我正在删除,重新创建,迁移和重新安装测试数据库,并在单元测试运行之前确认数据存在。)

结果是这个断言在seeds.rb中成功但在一行测试中失败了:

assert_equal 51, State.all.size

1) Failure:
test_state_seeds_are_present(StateTest) [/test/unit/state_test.rb:24]:
<51> expected but was
<0>.
1 tests, 1 assertions, 1 failures, 0 errors

我已尝试在基本测试类fixtures语句中显式列出非状态模型,以及翻转事务fixtures标志(正如预期的那样,这只会影响测试期间创建的记录)。当然,正在考虑的测试本身并没有删除这些记录。

状态记录始终被删除。有没有办法告诉Rails只是脱掉种子数据?我是否需要复制灯具中的所有数据以确保它重新加载?如果没有重大政治事件,我预计州的数据会相对稳定。

TIA

6 个答案:

答案 0 :(得分:12)

测试删除数据库中的所有数据,然后加载你的灯具(如果你有的话)。

您需要让测试帮助程序在测试运行之前加载种子文件。有几种方法可以做到这一点,请查看我的类似问题:How to load db:seed data into test database automatically?

最简单的方法可能只是添加

require "#{Rails.root}/db/seeds.rb"

到test_helper.rb文件的顶部(假设您使用内置测试框架)。

答案 1 :(得分:4)

“种子”功能未集成到测试体系结构中。测试是围绕灯具构建的,每次运行测试套件时,Rails都会加载灯具中的数据并替换现有内容。

但是,使用种子数据填充数据库非常简单。

在test_helper.rb文件中,在基础ActionSupport::TestCase类中添加新的设置方法。

class ActionSupport::TestCase < ...

  setup :load_seeds

  protected 

    def load_seeds
      load "#{Rails.root}/db/seeds.rb"
    end

end

答案 2 :(得分:0)

我同意weppos关于这样做的最佳方法,但是为了完整性,并且为了那些可能已经拥有夹具文件的人,您可以采用其他方法并从现有灯具中种植数据库。 / p>

这可以通过在db / seeds.rb文件中执行以下操作来完成

RAILS_FIXTURES = "#{Rails.root}/spec/fixtures"

models_loaded_from_fixtures = %w[Modela Modelb Modelc ....]

models_loaded_from_fixtures.each do |model|
  Fixtures.create_fixtures(RAILS_FIXTURES, "#{model.tableize}")
  puts "Loaded #{model.constantize.all.size} #{model.pluralize}"
end

您也可以阅读fixures目录并创建一个要处理的文件名数组,我选择了上面的过程,因为我希望能够指定我希望在DB中使用的许多现有灯具中的哪一个。

答案 3 :(得分:0)

我怀疑是否需要首先编写类似的测试。您是否正在测试种子数据rake任务是否正常工作,或者您是否要测试State类实现的行为?我假设后者,所以我会编写专注于行为的测试并使用Factory Girl(或类似的)因为你提到你没有使用灯具。请务必从fixtures :all删除test/test_helper.rb行。

要将任务注入正常的运行测试流程,这种方法一直对我有用:

namespace :test do
  task :force_environment do
    ENV['RAILS_ENV'] = 'test'
    RAILS_ENV.replace('test')
  end
end

%w(test:units test:functionals test:integration).map do |task_name|
  task = Rake::Task[task_name]
  task.clear_prerequisites

  task.enhance %w(db:test:prepare test:force_environment db:seed)
end

只需将其放在名为lib/tasks/testing.rake的文件中,当您下次运行rake test或其他与测试相关的任务时,它就会被接收。

答案 4 :(得分:0)

我遇到了同样的问题,但标准答案对我不起作用。

我的问题涉及类文件,它们对常量和named_scopes进行数据库查找。我找不到任何方法在适当的时间加载种子数据。

我确实找到了绕过删除的方法,即使我删除了缺失表的夹具文件,也会发生这种情况。

RAILS_ENV =测试rake db:seed ruby -Itest test / units / * .rb

答案 5 :(得分:0)

默认情况下,您无法同时应用seedfixtures来设置相同的table数据。

例如。如果您设置名为products.yml的灯具,它将&#34;从产品中删除数据&#34;在创建fixtures期间。

你可以:

  1. seed的阶段移到fixtures后面(手动加载种子);
  2. 只使用其中一种或另一种方法来管理测试数据;
  3. 不要使用这两种方法来设置相同的表格数据;
  4. 在Rails4.2中,您可以在test_helper.rb中破解此line 像这样:
  5. &GT;

    require 'rails/test_help'
    
    class ActiveRecord::FixtureSet
      def self.create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base)
        ...
        # table_rows.each_key do |table|
        #   conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete'
        # end
        ...
      end
    

    这会对某些遗留情况有所帮助,但弄乱seedsfixtures可能会带来新问题。