57

I'm using rspec for testing w my rails 3 app. I need to seed the database before the tests start. How can I seed the database with the following:

/db/seeds.rb

["Admin", "Member"].each do |role_name|
  Role.find_or_create_by_name(role_name)
end

Thanks

user456584
  • 86,427
  • 15
  • 75
  • 107
AnApprentice
  • 108,152
  • 195
  • 629
  • 1,012

6 Answers6

211

In spec_helper.rb or rails_helper.rb:

RSpec.configure do |config|
  config.before(:suite) do
    Rails.application.load_seed # loading seeds
  end
end
Hannes
  • 2,451
  • 2
  • 18
  • 11
  • 4
    I needed to explicitly add the 'database_cleaner' gem to my `:test` group in my gemfile to get DatabaseCleaner working. – Harry Moreno Jan 09 '14 at 00:42
  • 3
    This worked great for me and now I'm wondering why it's not gotten more upvotes or shown up elsewhere – Ben Saufley Mar 13 '14 at 02:18
  • 1
    Not requiring another gem when using the basic seeding functionality is much nicer with this. – Keith Smiley Apr 15 '14 at 21:19
  • 1
    Works for me after I added to `rails_helper.rb` instead of `spec_helper.rb`. – srk Nov 07 '19 at 04:52
  • How do i use this to add a different seeds file besides the main seeds file? I'd like a much smaller one for my tests – Jeremy Moritz Jan 29 '20 at 13:42
  • 1
    Hi @JeremyMoritz I would do this in similar way like here explained https://medium.com/@ethanryan/split-your-rails-seeds-file-into-separate-files-in-different-folders-3c57be765818 . I hope this will help out. – Hannes Feb 06 '20 at 08:41
24

However Scott's solution surely works for you, I believe the better way to solve your problem was to put the code responsible for seeding your test database within RSpec's configure block:

I use SeedFu and in my spec_helper I have:

RSpec.configure do |config|

  # some other configuration code ...

  config.before(:suite) do
    # ...
    SeedFu.seed
    # ...
  end

  # some other configuration code ...

end
Michał Czapko
  • 1,948
  • 1
  • 16
  • 25
12

I've followed the raging debate over at Auto-load the seed data from db/seeds.rb with rake. Die-hards maintain that you should never load seed data for tests, but I take the more moderate stance that there are occasions where you might want to load seed data for specific tests, e.g. verifying that the seed data exists.

Unlike some answers given here, I do not recommend unconditionally loading the seeds from inside your spec_helper file. Instead, you can load your seeds using before :each or before :all inside just those test files that need the seeds, e.g.:

describe "db seed tests" do
  before(:each) do
    load "#{Rails.root}/db/seeds.rb" 
  end

  ...your test code here...
end

update

As @marzapower points out, if you go this route, your seeds.db file should clear each table before creating entries or use find_or_create_by methods. (Hint: the former is faster and more reliable.) This will prevent duplicate entries if you load the seeds.db file more than once.

Community
  • 1
  • 1
fearless_fool
  • 33,645
  • 23
  • 135
  • 217
  • This approach only works for the first call after a `db:reset`. Every sequent call will duplicate data. – marzapower Dec 02 '13 at 21:40
  • 1
    @marzapower: Good catch -- I should have mentioned that my seeds.db file always drops the tables before populating them for the very reason you mention. Alternately, the seeds.db file can use `find_or_create` to avoid creating duplicates. – fearless_fool Dec 03 '13 at 13:04
12

Try, something like this

rake db:seed RAILS_ENV=test

You can get a list of all rake commands doing

rake -T

If this is test data, you may want to look at putting it into fixtures which will be loaded on the start of the tests.

iwasrobbed
  • 46,496
  • 21
  • 150
  • 195
Scott
  • 1,105
  • 1
  • 7
  • 17
  • This will seed data for the development database, not the test database. Add RAILS_ENV=test to seed the test database. – RyanW Dec 17 '11 at 06:43
10

To load seeds in rspec you need to add it after database cleanup in confg.before(:suite) in spec_helper

config.before(:suite) do
  DatabaseCleaner.clean_with(:truncation)
  load Rails.root.join('db', 'seeds.rb')
end
Jason Swett
  • 43,526
  • 67
  • 220
  • 351
Ahmad Hussain
  • 2,443
  • 20
  • 27
2

I ended up needing to use DatabaseCleaner to truncate the database, then load the rake task that does my seeding (because I use seedbank). After that, I wound up wrapping my tests in a transaction like on the database_cleaner README, so that each test could run with a freshly loaded site.

RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
    MyApplicationName::Application.load_tasks
    Rake::Task['db:seed'].invoke # loading seeds
  end
  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end
  end
end
Loren
  • 3,476
  • 3
  • 23
  • 15