at.
at.

Reputation: 52500

How to seed test data in Rails not using seeds.rb?

I have seeds.rb populating my development database. And I know I can easily apply seeds.rb to my test database using:

rake db:seed RAILS_ENV=test

However, I want a different seeds.rb file to populate my test database. Maybe seeds_test.rb. This must be an extremely common requirement among rails programmers, isn't it?

If there's no easy way to do this, like rake db:seed:seeds_test RAILS_ENV=test, then how would I create a rake task? I would think something like this in lib/tasks/test_seeds.rake:

namespace :db do
  desc "Seed data for tests"
  task :seed_test => :environment do
    load "#{Rails.root}/db/seeds_test.rb"
  end
end

I think that'll work, but then I would love for my rake task to automatically know to apply this only to the test database without me having to specify:

rake db:seed_test RAILS_ENV=test

How do I get the rake task so all I have to enter in the command line is:

rake db:seed_test

UPDATE: Another stackoverflow question was linked to where the answer was to do this:

Rails.env = 'test'

Unfortunately that doesn't actually do anything (at least as of Rails 4.2) :(.

Upvotes: 3

Views: 6977

Answers (2)

das-g
das-g

Reputation: 9994

In db/seeds.rb, test for the value of Rails.env and execute the respective seeding:

#db/seeds.rb
case Rails.env
when 'development'
  # development-specific seeds ...
  # (anything you need to interactively play around with in the rails console)

when 'test'
  # test-specific seeds ...
  # (Consider having your tests set up the data they need
  # themselves instead of seeding it here!)

when 'production'
  # production seeds (if any) ...

end

# common seeds ...
# (data your application needs in all environments)

If you want to use separate files, just require them inside this structure, e.g.:

#db/seeds.rb
case Rails.env
when 'development'
  require 'seeds_development'    
when 'test'
  require 'seeds_test'
when 'production'
  require 'seeds_production'
end

require 'seeds_common'

or shorter

#db/seeds.rb
require "seeds_#{Rails.env}"
require 'seeds_common'

Upvotes: 12

das-g
das-g

Reputation: 9994

If you are using spring, you can set a Rails environment for a rake task:

# config/spring.rb
Spring::Commands::Rake.environment_matchers['db:seed_test'] = "test"

or for all tasks matching a regex pattern:

# config/spring.rb
Spring::Commands::Rake.environment_matchers[/^db:.+_test$/] = "test"

This allows you to call

rake db:seed_test

and have it run in the test Rails environment, thus writing to your test DB.

However, this doesn't have any effect

  • if spring isn't used for rake
    or
  • if the rake task isn't invoked directly (e.g. from the command line) but as a dependency of another rake task not matching the pattern

Upvotes: 0

Related Questions