db:seedデータをテストデータベースに自動的にロードする方法


122

Rails 2.3.4+でシードデータをロードする新しい標準的な方法であるdb:seedrakeタスクを使用しようとしています。

アプリケーションが実際に正しく機能するために必要な定数データをロードしています。

db:seedテストの前にタスクを実行してデータを事前入力するための最良の方法は何ですか?

回答:


120

db:seedrakeタスクは、主にだけロードするdb/seeds.rbスクリプトを。したがって、そのファイルを実行してデータをロードするだけです。

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

# or

Rails.application.load_seed

どこに配置するかは、使用しているテストフレームワークと、すべてのテストの前にロードするか、最初に一度だけロードするかによって異なります。あなたはそれをsetup通話やtest_helper.rbファイルに置くことができます。


4
私は単純さを気に入っていますが、何らかの理由でこの行を追加test_helper.rbしたのですが、stackoverflow.com / a / 1998520/68210は機能しました。
ダニエルXムーア

37
Railsの新しいバージョンでは、次のことができます。Rails.application.load_seed
Steve

@Steveありがとう-たとえば、rspec / capybarraを使用している場合、Rails.application.load_seedをどこに置くか知っていますか?
BKSpurgeon

1
@BKSpurgeon特定のデータを実行する必要があり、ファクトリが複雑すぎるため、アプリケーションにシードデータをかなりロードします。私は入れてRails.application.load_seed右下のrequire 'rspec/rails' 私のrails_helperファイルに。database_cleaner gemを使用している場合-各テストの後にシードデータを失わないようにするために少し調整する必要があります。それはgemのドキュメントで確認できます
MageeWorld

Rails 5.xでは、これをtest/test_helper.rb既存のrequire 'rails/test_help'行の後に追加しました
Andrew

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:loadは実行されないため(db:test:clone_structure is)


4
でレイクを実行--traceすると、これがどのように機能するかを理解するのに役立ちました。
Jared Beck

4
@BookOfGreg自分で作成したlib / tasks / test_seed.rakeにあります
Eugene Bolshakov

6
なぜこれだけではないのですか? task 'db:test:prepare' => 'db:seed'
Carson Reinke 2013年

3
Rails 4.0.0の場合、ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])前に最終追加Rake::Task["db:seed"].invoke
janic_ '

3
@CarsonReinke- db:seed実行時の環境がdevelopment奇妙なことに...
denishaskin 2013

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

15

上記のスティーブのコメントは正解だと思います。を使用Rails.application.load_seedして、シード環境データをテスト環境にロードできます。ただし、このデータが読み込まれるタイミングと頻度は、いくつかの要因によって異なります。

Minitestの使用

すべてのテストの前にこのファイルを1回実行する便利な方法はありません(このGithubの問題を参照)。各テストの前に、おそらくテストファイルのセットアップ方法で、データを1回ロードする必要があります。

# 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

お役に立てれば。


2
これまでのベストアンサー
Yuri Ghensev 2016年

同様のことを行いますが、のbefore(:suite)代わりに呼び出しbefore(:all)ます。フォーマットされたコードを含めるために別の回答を投稿しました。
Mark Schneider

3

次のように、db:test:prepareの一部としてdb:seedを呼び出しています。

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

このようにして、シードデータはテストクラス全体ではなく、テスト実行全体で1回読み込まれます。


4
そのための新しいdb:test:prepareタスクを作成しましたか?コードを投稿できますか?
ルーク・フランクル、2009年

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

2

rakeタスクに追加Rake::Task["db:seed"].invokeしてもdb:test:prepareうまくいきませんでした。でデータベースを準備しrake db:test:prepare、テスト環境内のコンソールに入ると、すべてのシードがそこにありました。しかし、種は私のテストの間持続しませんでした。

load "#{Rails.root}/db/seeds.rb"しかし、私のセットアップ方法に追加することはうまくいきました。

これらのシードを自動的にロードして永続化したいのですが、それを行う方法がまだ見つかりません!


0

マットの答えに基づいて、そのようなルートを取る場合は、ファイルRails.application.load_seed内のbefore(:suite)ブロックでrspec_helper.rbはなく、ブロック内で呼び出すことをお勧めしbefore(:all)ます。このようにして、シードコードは、テストグループごとに1回ではなく、テストスイート全体に対して1回だけ呼び出されます。

rspec_helper.rb:

RSpec.configure do |config|
  ...
  config.before(:suite) do
    Rails.application.load_seed
  end
  ...
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.