Jak automatycznie załadować db: seed data do testowej bazy danych?


122

Próbuję użyć nowego standardowego sposobu ładowania danych początkowych w Railsach 2.3.4+, db:seedzadaniu rake.

Ładuję stałe dane, które są wymagane, aby moja aplikacja naprawdę działała poprawnie.

Jaki jest najlepszy sposób uruchomienia db:seedzadania przed testami, aby dane zostały wstępnie wypełnione?

Odpowiedzi:


120

db:seedZadaniem natarcia głównie właśnie ładuje db/seeds.rbskrypt. Dlatego po prostu wykonaj ten plik, aby załadować dane.

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

# or

Rails.application.load_seed

Gdzie to umieścić, zależy od używanego frameworka testowego i czy chcesz, aby był ładowany przed każdym testem, czy tylko raz na początku. Możesz umieścić to w setuprozmowie lub w test_helper.rbpliku.


4
Uwielbiam prostotę, ale z jakiegoś powodu dodanie tej linii do mojej test_helper.rbnie zadziałało, chociaż stackoverflow.com/a/1998520/68210 tak.
Daniel X Moore

37
W nowszych wersjach szyn możesz to zrobić: Rails.application.load_seed
Steve

@Steve dziękuję - czy wiesz, gdzie umieścić Rails.application.load_seed, jeśli na przykład używa się rspec / capybarra?
BKSpurgeon

1
@BKSpurgeon Ładuję dane początkowe dość często w moich aplikacjach, ponieważ wymagają one określonych danych do uruchomienia, a fabryka jest po prostu zbyt skomplikowana. I umieścić Rails.application.load_seedtuż pod require 'rspec/rails' moim pliku rails_helper. Jeśli używasz klejnotu database_cleaner - będzie to wymagało drobnych poprawek, aby upewnić się, że nie stracisz danych z nasion po każdym teście i możesz to znaleźć w dokumentacji gem it self
MageeWorld

W Railsach 5.x dodałem to test/test_helper.rbpo istniejącej require 'rails/test_help'linii
Andrew

87

Powiedziałbym, że tak powinno być

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

Ponieważ db: test: load nie jest wykonywany, jeśli masz config.active_record.schema_format =: sql (db: test: clone_structure to)


4
Uruchomienie rake z --tracepomogło mi zrozumieć, jak to działa.
Jared Beck

4
@BookOfGreg Mam to w lib / task / test_seed.rake, które stworzyłem sam
Eugene Bolshakov

6
Dlaczego nie tylko to? task 'db:test:prepare' => 'db:seed'
Carson Reinke

3
Dla Rails 4.0.0 ostateczne dodanie ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])przedRake::Task["db:seed"].invoke
janic_

3
@CarsonReinke - bo wtedy środowisko po db:seeduruchomieniu jest development... dziwne.
denishaskin

17

Umieszczenie czegoś takiego w lib / task / test_seed.rake powinno wywołać zadanie seed po db: test: load:

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

15

Uważam, że powyższy komentarz Steve'a powinien być poprawną odpowiedzią. Możesz użyć Rails.application.load_seeddo załadowania danych nasion do środowiska testowego. Jednak to, kiedy i jak często te dane są ładowane, zależy od kilku rzeczy:

Korzystanie z programu Minitest

Nie ma wygodnego sposobu na jednorazowe uruchomienie tego pliku przed wszystkimi testami (zobacz ten problem na Githubie ). Będziesz musiał załadować dane raz przed każdym testem, prawdopodobnie w metodzie konfiguracji plików testowych:

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

  def setup
    Rails.application.load_seed
  end

  # tests here...

end

Korzystanie z RSpec

Użyj before(:all)metody RSpec, aby załadować dane początkowe dla wszystkich testów dla tego modelu:

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

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

Mam nadzieję że to pomoże.


2
Najlepsza jak dotąd odpowiedź
Yuri Ghensev

Robię coś podobnego, z tym wyjątkiem, że wywołuję to before(:suite)zamiast before(:all). Wysłałem osobną odpowiedź zawierającą sformatowany kod.
Mark Schneider

3

Wywołujemy db: seed jako część db: test: ready, z:

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

W ten sposób dane początkowe są ładowane raz na cały przebieg testu, a nie raz na klasę testową.


4
Czy utworzyłeś nową bazę danych: test: przygotuj zadanie, aby to zrobić? Czy możesz wysłać kod?
Luke Francl

3

Dla tych, którzy używają banku nasion, zmienia sposób ładowania nasion, więc prawdopodobnie nie możesz / nie chcesz korzystać z load ...rozwiązania przedstawionego tutaj.

Rake::Task['db:seed'].invokeSamo wprowadzenie do test_helper zaowocowało:

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

Ale kiedy dodaliśmy wcześniej load_tasks, zadziałało:

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

2

Dodawanie Rake::Task["db:seed"].invokedo db:test:preparezadania prowizji nie działa dla mnie. Jeśli przygotowałem bazę danych za pomocą rake db:test:prepare, a następnie wszedłem do konsoli w środowisku testowym, wszystkie moje nasiona były tam. Jednak nasiona nie przetrwały między moimi testami.

Dodanie load "#{Rails.root}/db/seeds.rb"do mojej metody konfiguracji działało jednak dobrze.

Chciałbym, aby te nasiona ładowały się automatycznie i utrzymywały się, ale nie znalazłem jeszcze sposobu, aby to zrobić!


0

Opierając się na odpowiedź Matta, jeśli przy tego rodzaju trasy, polecam dzwoniąc Rails.application.load_seedw before(:suite)bloku w rspec_helper.rbzamiast w before(:all)bloku w każdym pliku. W ten sposób kod inicjujący jest wywoływany tylko raz dla całego zestawu testów, a nie raz dla każdej grupy testów.

rspec_helper.rb:

RSpec.configure do |config|
  ...
  config.before(:suite) do
    Rails.application.load_seed
  end
  ...
end
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.