How to load db:seed data into test database automatically?
I'm attempting to use the new standard way of loading seed data in Rails 2.3.4+, the db:seed
rake task.
I'm开发者_如何学编程 loading constant data, which is required for my application to really function correctly.
What's the best way to get the db:seed
task to run before the tests, so the data is pre-populated?
The db:seed
rake task primarily just loads the db/seeds.rb
script. Therefore just execute that file to load the data.
load "#{Rails.root}/db/seeds.rb"
# or
Rails.application.load_seed
Where to place that depends on what testing framework you are using and whether you want it to be loaded before every test or just once at the beginning. You could put it in a setup
call or in a test_helper.rb
file.
I'd say it should be
namespace :db do
namespace :test do
task :prepare => :environment do
Rake::Task["db:seed"].invoke
end
end
end
Because db:test:load is not executed if you have config.active_record.schema_format = :sql (db:test:clone_structure is)
Putting something like this in lib/tasks/test_seed.rake should invoke the seed task after db:test:load:
namespace :db do
namespace :test do
task :load => :environment do
Rake::Task["db:seed"].invoke
end
end
end
I believe Steve's comment above should be the correct answer. You can use Rails.application.load_seed
to load seed data into your test envoironment. However, when and how often this data is loaded depends on a few things:
Using Minitest
There is no convenient way to run this file once before all tests (see this Github issue). You'll need to load the data once before each test, likely in the setup method of your test files:
# test/models/my_model_test.rb
class LevelTest < ActiveSupport::TestCase
def setup
Rails.application.load_seed
end
# tests here...
end
Using RSpec
Use RSpec's before(:all)
method to load seed data for all test for this model:
describe MyModel do
before(:all) do
Rails.application.load_seed
end
describe "my model..." do
# your tests here
end
Hope this helps.
Building on Matt's answer, if taking that sort of route, I recommend calling Rails.application.load_seed
in a before(:suite)
block in rspec_helper.rb
rather than in a before(:all)
block in any file. That way the seeding code is invoked only once for the entire test suite rather than once for each group of tests.
rspec_helper.rb:
RSpec.configure do |config|
...
config.before(:suite) do
Rails.application.load_seed
end
...
end
We're invoking db:seed as a part of db:test:prepare, with:
Rake::Task["db:seed"].invoke
That way, the seed data is loaded once for the entire test run, and not once per test class.
Adding Rake::Task["db:seed"].invoke
to the db:test:prepare
rake task did not work for me. If I prepared the database with rake db:test:prepare
, and then entered the console within the test environment, all my seeds were there. However, the seeds did not persist between my tests.
Adding load "#{Rails.root}/db/seeds.rb"
to my setup method worked fine, though.
I would love to get these seeds to load automatically and persist, but I haven't found a way to do that yet!
For those using seedbank, it changes how seeds are loaded, so you probably can't/don't want to use the load ...
solution provided here.
And just putting Rake::Task['db:seed'].invoke
into test_helper resulted in:
Don't know how to build task 'db:seed' (RuntimeError)
But when we added load_tasks before that, it worked:
MyApp::Application.load_tasks
Rake::Task['db:seed'].invoke
精彩评论