Автоматическая загрузка данных семян из db / seeds.РБ с граблями

Я использую rails-rspec камень и у меня есть несколько спецификаций (модели, контроллеры и т. д.). Когда я бегу:

bundle exec rake

все проверяется. Тем не менее, я хотел бы улучшить свои спецификации, заполнив некоторые данные (из db/seeds.rb) сразу после создания базы данных (в тестовой среде).

мой спец/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

что может сделать лучший способ сделать это? Спасибо.

7 ответов


В зависимости от того, как настроен ваш семенной файл, вы можете просто загрузить/запустить его из before(:each) или before(:all) блок:

load Rails.root + "db/seeds.rb" 

плохая идея! Никогда, никогда не засевайте свою тестовую базу данных. Используйте фабрики для создания, в каждом тесте,только записи, необходимые для прохождения этого теста. Заполнение тестовой базы данных сделает ваши тесты менее надежными, потому что вы будете делать много предположений, которые явно не указаны в ваших тестах.


Я создал свой rake spec задача для автоматической загрузки db / seeds.rb, поэтому я полагаюсь на это для настройки базы данных для первого запуска. Добавьте это в свой Rakefile:

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

затем, при последующих запусках я просто вызываю rspec spec сразу пропустить шаг семени и избежать ненужной перезагрузки. Я настраиваю database cleaner, чтобы игнорировать таблицы seed следующим образом:

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

это усечь все после выполнения примера, кроме таблиц seed. предполагается, что вы никогда ничего не пишете в таблицы семян! это, как правило, безопасное предположение, так как исходные данные обычно статичны.

для всех других нормальных сценариев я зависел от транзакций для отката любых вставленных записей. База данных возвращается в исходное состояние, при этом данные в исходных таблицах остаются нетронутыми. Безопасно писать в таблицы семян здесь, Если вам нужно.

восстановить таблицы семян, вам просто нужно запустить rake spec снова.


чтобы загрузить семена в rspec, вам нужно добавить его после очистки базы данных в confg.before (: suite) in spec_helper

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

на рельсы 4.2.0 и RSpec 3.x, вот как мой rails_helper.РБ смотрит.

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

  1. скопировать семян.файл rb внутри папки config/initializers.Итак, семя.файл rb будет выполнен при запуске сервера.

  2. выполните приведенную ниже команду, чтобы заполнить тестовую БД семенем.данные

    RAILS_ENV=тестовые грабли db: seed


Я думаю, что мы должны использовать

config.before(:each) do
  Rails.application.load_seed # loading seeds
end

as before (: all) запускает блок один раз перед запуском всех примеров.

Итак, если мы используем тег before :all, начальные данные будут очищены.