Come caricare automaticamente db: seed data nel database di test?


122

Sto tentando di utilizzare il nuovo modo standard di caricare i dati seed in Rails 2.3.4+, il db:seedrake task.

Sto caricando dati costanti, necessari affinché la mia applicazione funzioni correttamente.

Qual è il modo migliore db:seedper eseguire l' attività prima dei test, in modo che i dati siano precompilati?

Risposte:


120

L' db:seedattività rake carica principalmente solo lo db/seeds.rbscript. Quindi basta eseguire quel file per caricare i dati.

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

# or

Rails.application.load_seed

Dove posizionarlo dipende dal framework di test che stai utilizzando e se vuoi che venga caricato prima di ogni test o solo una volta all'inizio. Potresti metterlo in una setupchiamata o in un test_helper.rbfile.


4
Adoro la semplicità, ma per qualche motivo l'aggiunta di questa riga al mio test_helper.rbnon ha funzionato per me, sebbene stackoverflow.com/a/1998520/68210 lo facesse.
Daniel X Moore,

37
Nelle versioni più recenti di rails puoi fare: Rails.application.load_seed
Steve

@Steve, grazie - sai dove mettere Rails.application.load_seed se uno usa rspec / capybarra, per esempio?
BKSpurgeon

1
@BKSpurgeon Carico un po 'i dati del seme nelle mie applicazioni perché richiede dati specifici per l'esecuzione e la fabbrica è semplicemente troppo complicata. Metto Rails.application.load_seedsubito sotto require 'rspec/rails' nel mio file rails_helper. Se stai usando database_cleaner gem, richiederà un piccolo ritocco per assicurarti di non perdere i tuoi dati seed dopo ogni test e puoi trovarlo nella documentazione della gemma stessa
MageeWorld

In Rails 5.x ho aggiunto questo test/test_helper.rbdopo la require 'rails/test_help'riga esistente
Andrew

87

Direi che dovrebbe essere

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

Perché db: test: load non viene eseguito se hai config.active_record.schema_format =: sql (db: test: clone_structure is)


4
L'esecuzione di rake con --tracemi ha aiutato a capire come funziona.
Jared Beck

4
@BookOfGreg Ce l'ho in lib / tasks / test_seed.rake che ho creato io stesso
Eugene Bolshakov

6
Perché non solo questo? task 'db:test:prepare' => 'db:seed'
Carson Reinke

3
Per Rails 4.0.0 aggiunta finale ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])primaRake::Task["db:seed"].invoke
janic_

3
@CarsonReinke - perché poi l'ambiente quando db:seedviene eseguito è development... stranamente.
denishaskin

17

Mettendo qualcosa di simile in lib / tasks / test_seed.rake dovrebbe richiamare l'attività seed dopo db: test: load:

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

15

Credo che il commento di Steve sopra dovrebbe essere la risposta corretta. È possibile utilizzare Rails.application.load_seedper caricare i dati del seme nell'ambiente di prova. Tuttavia, quando e quanto spesso questi dati vengono caricati dipende da alcune cose:

Utilizzando Minitest

Non esiste un modo conveniente per eseguire questo file una volta prima di tutti i test (vedere questo problema di Github ). Dovrai caricare i dati una volta prima di ogni test, probabilmente nel metodo di configurazione dei tuoi file di test:

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

  def setup
    Rails.application.load_seed
  end

  # tests here...

end

Utilizzando RSpec

Usa il before(:all)metodo di RSpec per caricare i dati seed per tutti i test per questo modello:

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

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

Spero che questo ti aiuti.


2
Migliore risposta finora
Yuri Ghensev

Faccio qualcosa di simile, tranne che lo sto invocando in before(:suite)invece di before(:all). Ha pubblicato una risposta separata per includere il codice formattato.
Mark Schneider

3

Stiamo invocando db: seed come parte di db: test: prepare, con:

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

In questo modo, i dati seed vengono caricati una volta per l'intera esecuzione del test e non una volta per classe di test.


4
Hai creato un nuovo db: test: prepare task per farlo? Puoi inserire il codice?
Luke Francl

3

Per coloro che utilizzano seedbank, cambia il modo in cui vengono caricati i semi, quindi probabilmente non puoi / non vuoi usare la load ...soluzione fornita qui.

E il solo inserimento Rake::Task['db:seed'].invokein test_helper ha prodotto:

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

Ma quando abbiamo aggiunto load_tasks prima, ha funzionato:

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

2

L'aggiunta Rake::Task["db:seed"].invokeall'attività di db:test:preparerastrello non ha funzionato per me. Se ho preparato il database con rake db:test:preparee poi sono entrato nella console all'interno dell'ambiente di test, tutti i miei semi erano lì. Tuttavia, i semi non persistevano tra i miei test.

L'aggiunta load "#{Rails.root}/db/seeds.rb"al mio metodo di installazione ha funzionato bene, però.

Mi piacerebbe che questi semi si caricassero automaticamente e persistessero, ma non ho ancora trovato un modo per farlo!


0

Basandosi sulla risposta di Matt, se si prende quel tipo di percorso, consiglio di chiamare Rails.application.load_seedun before(:suite)blocco rspec_helper.rbpiuttosto che un before(:all)blocco in qualsiasi file. In questo modo il codice di seeding viene richiamato solo una volta per l'intera suite di test anziché una volta per ogni gruppo di test.

rspec_helper.rb:

RSpec.configure do |config|
  ...
  config.before(:suite) do
    Rails.application.load_seed
  end
  ...
end
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.