web-dev-qa-db-ja.com

rakeを使用してdb / seeds.rbからシードデータを自動ロードします

私はRails-rspec gemを使用しており、いくつかの仕様(モデル、コントローラーなど)があります。私が走るとき:

bundle exec rake

すべてがテストされます。ただし、データベースが(テスト環境で)作成された直後に(db/seeds.rbから)いくつかのデータをシードすることにより、仕様を改善したいと思います。

私のspec/spec_helper.rbファイルは次のようになります。

ENV["Rails_ENV"] ||= 'test'

require File.expand_path("../../config/environment", __FILE__)
require 'rspec/Rails'
require 'capybara/rspec'
require 'Ruby-debug'

# Requires supporting Ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

RSpec.configure do |config|
  config.mock_with :rspec

  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = false

  config.include SpecHelper

  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.start
    stub_xmpp_rest_client!  
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

  config.include Devise::TestHelpers, :type => :controller
  config.include Delorean
  config.after(:each) { back_to_the_present }
  config.include Factory::Syntax::Methods
  config.extend ControllerMacros, :type => :controller
end

そうするための最良の方法は何でしょうか?ありがとう。

20
Zag zag..

シードファイルの構成方法によっては、before(:each)またはbefore(:all)ブロックからシードファイルをロード/実行できる場合があります。

load Rails.root + "db/seeds.rb" 
29
Taryn East

悪いアイデア!テストデータベースにシードを設定しないでください。工場を使用して、各テスト内にのみそのテストに合格するために必要なレコードを作成します。テストデータベースにシードを設定すると、テストで明示的に指定されていない多くの仮定を行うため、テストの信頼性が低下します。

44

Db/seeds.rbを自動的にロードするようにrake specタスクを設定したので、最初の実行のためにデータベースを設定するためにそれに依存しています。これをRakefileに追加します。

task :spec     => "db:seed"
task :cucumber => "db:seed"

その後の実行では、rspec specを直接呼び出して、シードステップをスキップし、不要なリロードを回避します。次のようにシードテーブルを無視するようにデータベースクリーナーを構成します。

RSpec.configure do |config|

  config.add_setting(:seed_tables)
  config.seed_tables = %w(countries roles product_types)

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation, except: config.seed_tables)
  end

  config.around(:each) do |example|
    if example.metadata[:no_transactions]
      DatabaseCleaner.strategy = :truncation, {except: config.seed_tables}
    else
      DatabaseCleaner.strategy = :transaction
    end
    DatabaseCleaner.start
    example.run
    DatabaseCleaner.clean
  end
end

コミットされたデータが必要なシナリオの場合、次を追加できます。

describe "commit for real", use_transactions: false do
  # ...
end

これにより、シードテーブルを除き、サンプルの実行後にすべてが切り捨てられます。 シードテーブルには何も書き込まないことを前提としています!シードデータは通常静的であるため、これは一般的に安全な前提です。

他のすべての通常のシナリオでは、挿入されたレコードをロールバックするためにトランザクションに依存しています。データベースは元の状態に戻り、シードテーブルのデータはそのままです。必要に応じて、ここでシードテーブルに書き込んでも安全です。

シードテーブルを再構築するには、rake specを再度実行する必要があります。

12
Andrew Vit

Rspecにシードをロードするには、データベースのクリーンアップ後にspec_helperのconfig.before(:suite)にシードを追加する必要があります。

config.before(:suite) do
  DatabaseCleaner.clean_with(:truncation)
  load "#{Rails.root}/db/seeds.rb" 
end
7
Ahmad Hussain

Rails 4.2.およびRSpec 3.xでは、これが私のRails_helper.rbの外観です。

RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = false

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

  config.before(:all) do
    Rails.application.load_seed # loading seeds
  end
end
7
Andrew Lobban
  1. config/initializersフォルダー内のseed.rbファイルをコピーします。したがって、seed.rbファイルはサーバーの起動時に実行されます。

  2. 以下のコマンドを実行して、テストデータベースにseed.rbデータを入力します

    Rails_ENV = test rake db:seed

0
vidur punj