Як автоматично завантажувати дані db: насіння в тестову базу даних?


122

Я намагаюся використовувати новий стандартний спосіб завантаження даних про насіння в Rails 2.3.4+, db:seedзавдання граблі.

Я завантажую постійні дані, які потрібні, щоб моя програма дійсно працювала правильно.

Який найкращий спосіб змусити db:seedвиконати завдання перед тестами, тому дані попередньо заповнені?

Відповіді:


120

Завдання db:seedграблі в першу чергу просто завантажує 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 .
Даніель Х Мур

37
У нових версіях рейок ви можете: Rails.application.load_seed
Стів

@Steve спасибі - чи знаєте ви, де поставити Rails.application.load_seed, якщо, наприклад, використовується rspec / capybarra?
BKSpurgeon

1
@BKSpurgeon Я досить завантажую дані про насіння у своїх додатках, оскільки для запуску потрібні конкретні дані, а фабрика - занадто складна. Я помістив Rails.application.load_seedпрямо require 'rspec/rails' у свій файл rails_helper. Якщо ви використовуєте gem database_cleaner gem - знадобиться трохи переробити, щоб переконатися, що ви не втратите свої дані про насіння після кожного тесту, і ви можете це знайти в документації самоцвіту
MageeWorld

У Rails 5.x я додав це test/test_helper.rbпісля існуючого require 'rails/test_help'рядка
Ендрю

87

Я б сказав, що так і має бути

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

Оскільки db: test: завантаження не виконується, якщо у вас config.active_record.schema_format =: sql (db: test: clone_structure is)


4
Запуск граблі --traceдопомагав мені зрозуміти, як це працює.
Джаред Бек

4
@BookOfGreg Я маю це у lib / task / test_seed.rake, який я створив сам
Євген

6
Чому б не просто це? task 'db:test:prepare' => 'db:seed'
Карсон Рейнке

3
Для Rails 4.0.0 заключне додавання ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])доRake::Task["db:seed"].invoke
janic_

3
@CarsonReinke - адже тоді середовище, коли db:seedпрацює, development... дивно.
денішаскін

17

Якщо щось подібне розміщувати в lib / task / 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

Немає зручного способу запустити цей файл один раз перед усіма тестами (див. Цю проблему Github ). Вам потрібно буде завантажувати дані один раз перед кожним тестом, ймовірно, у способі настройки ваших тестових файлів:

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

  def setup
    Rails.application.load_seed
  end

  # tests here...

end

Використання RSpec

Використовуйте before(:all)метод RSpec для завантаження даних про насіння для всіх тестів для цієї моделі:

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

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

Сподіваюся, це допомагає.


2
Найкраща відповідь поки що
Юрій Генцев

Я роблю щось подібне, за винятком того, що я посилаюсь на це before(:suite)замість before(:all). Опублікував окрему відповідь, щоб включити відформатований код.
Марк Шнайдер

3

Ми викликаємо db: seed як частину db: test: підготовка, з:

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

Таким чином, дані насіння завантажуються один раз за весь пробний пробіг, а не один раз за тестовий клас.


4
Чи створили ви новий db: test: підготуйте завдання для цього? Чи можете ви опублікувати код?
Люк Франкл

3

Для тих, хто використовує насіннєвий банк, він змінює завантаження насіння, тому, ймовірно, ви не можете / не бажаєте використовувати тут запропонований load ...розчин.

І тільки введення Rake::Task['db:seed'].invokeв test_helper призвело до:

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

Але коли ми додавали load_tasks до цього, це спрацювало:

MyApp::Application.load_tasks
Rake::Task['db:seed'].invoke

2

Додавання 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) блок у будь-якому файлі. Таким чином висівають код посіву лише один раз для всього тестового набору, а не один раз для кожної групи тестів.

rspec_helper.rb:

RSpec.configure do |config|
  ...
  config.before(:suite) do
    Rails.application.load_seed
  end
  ...
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.