13

我正在使用 seed.rb 来填充一些状态模型参考数据:

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

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

结果是这个断言在 seed.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

我已经尝试在基本测试类夹具语句中明确列出非状态模型,以及翻转事务夹具标志(正如预期的那样,这只会影响测试期间创建的记录)。自然,正在考虑的测试本身不会删除这些记录。

状态记录总是被删除。有没有办法让 Rails 从种子数据中解放出来?我是否需要复制夹具中的所有数据以确保重新加载?在没有重大政治事件的情况下,我预计州数据将相对稳定。

蒂亚

4

6 回答 6

12

测试从数据库中删除所有数据,然后加载您的设备(如果有的话)。

你需要让你的测试助手在测试运行之前加载种子文件。有几种方法可以做到这一点,看看我的类似问题:如何将 db:seed 数据自动加载到测试数据库中?

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

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

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

于 2009-12-14T04:24:58.857 回答
4

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

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

在您的 test_helper.rb 文件中,在基ActionSupport::TestCase类中添加一个新的 setup 方法。

class ActionSupport::TestCase < ...

  setup :load_seeds

  protected 

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

end
于 2009-12-14T08:12:48.520 回答
0

我同意 weppos 的最佳方法,但是为了完整性和可能已经拥有夹具文件的人,您可以采用其他方法并从现有夹具中为您的数据库播种。

这是通过在 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 的种子。

于 2009-12-14T10:35:03.400 回答
0

我质疑是否需要首先编写这样的测试。您是在测试种子数据 rake 任务是否正常工作,还是要测试您的 State 类实现的行为?我假设是后者,所以我会编写专注于行为的测试并使用 Factory Girl(或类似的),因为您提到您没有使用固定装置。确保fixtures :alltest/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

于 2009-12-14T15:04:35.563 回答
0

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

我的问题涉及类文件中的位置,这些文件对常量和命名范围进行了数据库查找。我找不到任何方法在正确的时间加载种子数据。

我确实找到了一种绕过删除的方法,即使我已经删除了丢失表的夹具文件,这种情况仍在发生。

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

于 2011-10-03T14:19:13.267 回答
0

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

例如。如果您设置了一个名为 的夹具products.yml,它将在创建期间“从产品中删除数据” fixtures

你可以:

  1. seed' 阶段移到 s 后面fixtures(手动加载种子);
  2. 仅使用其中一个,或使用另一种方法来管理测试数据;
  3. 不要同时使用这两种方法来设置同一个表的数据;
  4. 在 Rails4.2 中,你可以像这样破解这条线test_helper.rb

>

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

这在一些遗留情况下会有所帮助,但混乱seeds和混乱fixtures可能会带来新的问题。

于 2018-04-20T05:50:36.420 回答