128

我正在尝试使用新的标准方法在 Rails 2.3.4+ 中加载种子数据,即db:seedrake 任务。

我正在加载常量数据,这是我的应用程序真正正常运行所必需的。

在测试之前让任务运行的最佳方法是什么db:seed,以便预先填充数据?

4

8 回答 8

128

db:seedrake 任务主要只是加载db/seeds.rb脚本。因此,只需执行该文件即可加载数据。

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

# or

Rails.application.load_seed

放置在哪里取决于您使用的测试框架以及您是希望在每次测试之前加载它还是只在开始时加载一次。您可以将其放入setup通话或test_helper.rb文件中。

于 2009-10-15T20:31:39.960 回答
87

我会说应该是

namespace :db do
  namespace :test do
    task :prepare => :environment do
      Rake::Task["db:seed"].invoke
    end
  end
end

因为如果您有 config.active_record.schema_format = :sql (db:test:clone_structure is),则不会执行 db:test:load

于 2010-01-04T09:52:55.523 回答
17

把这样的东西放在 lib/tasks/test_seed.rake 应该在 db:test:load 之后调用种子任务:

namespace :db do
  namespace :test do
    task :load => :environment do
      Rake::Task["db:seed"].invoke
    end
  end
end
于 2009-12-01T22:52:48.930 回答
17

我相信史蒂夫上面的评论应该是正确的答案。您可以使用Rails.application.load_seed将种子数据加载到您的测试环境中。但是,加载此数据的时间和频率取决于以下几点:

使用 Minitest

在所有测试之前没有方便的方法运行此文件一次(请参阅此 Github 问题)。您需要在每次测试之前加载一次数据,可能在测试文件的设置方法中:

# test/models/my_model_test.rb
class LevelTest < ActiveSupport::TestCase

  def setup
    Rails.application.load_seed
  end

  # tests here...

end

使用 RSpec

使用 RSpec 的before(:all)方法为该模型的所有测试加载种子数据:

describe MyModel do
  before(:all) do
  Rails.application.load_seed
end

describe "my model..." do
  # your tests here
end

希望这可以帮助。

于 2016-08-23T21:09:18.713 回答
3

我们调用 db:seed 作为 db:test:prepare 的一部分,其中:

Rake::Task["db:seed"].invoke

这样,种子数据在整个测试运行中加载一次,而不是每个测试类加载一次。

于 2009-10-15T22:07:36.870 回答
3

添加Rake::Task["db:seed"].invokedb:test:preparerake 任务对我不起作用。如果我用 准备好数据库rake db:test:prepare,然后在测试环境中进入控制台,我所有的种子都在那里。但是,种子在我的测试之间没有持续存在。

不过,添加load "#{Rails.root}/db/seeds.rb"到我的设置方法中效果很好。

我很想让这些种子自动加载并持续存在,但我还没有找到一种方法来做到这一点!

于 2012-09-19T02:59:50.940 回答
3

对于那些使用种子库的人,它会改变种子的加载方式,因此您可能不能/不想使用load ...此处提供的解决方案。

只是放入Rake::Task['db:seed'].invoketest_helper 导致:

Don't know how to build task 'db:seed' (RuntimeError)

但是当我们在此之前添加 load_tasks 时,它起作用了:

MyApp::Application.load_tasks
Rake::Task['db:seed'].invoke
于 2014-02-17T22:06:02.667 回答
3

基于马特的回答,如果采用这种方式,我建议调用Rails.application.load_seed一个before(:suite)rspec_helper.rb而不是before(:all)任何文件的块。这样,种子代码只为整个测试套件调用一次,而不是为每组测试调用一次。

rspec_helper.rb:

RSpec.configure do |config|
  ...
  config.before(:suite) do
    Rails.application.load_seed
  end
  ...
end

于 2020-05-26T17:00:22.530 回答