Using seeds.rb data for testing is a bad idea

My app’s database has some static tables for which the data will stay more or less unchanged throughout the life of the app. Two of the many examples are:

  • List of world cities
  • List of roles that users can be assigned to

I was using seeds.rb to seed my production app, and I used the following code

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

located in lib/tasks/test_seed.rake

which seeded the database each time I ran

rake test:prepare

This was a BAD IDEA, because:

  • With more complex model specs, I have to clean out all the data in the db before running the test suite, otherwise I will get lots of failed tests that actually should be passing.
  • But when I cleaned out the db using the database_cleaner gem, that always got rid of my seeded data, which also returned lots of failed tests that should have been passing.
  • To make the test suite run correctly, I had to run
    rake test:prepare

    before every single test suite.

Instead, I refactored all my tests to create cities and roles on the fly using FactoryGirl, with code like this:

let(:user) { FactoryGirl.create(:user) }
FactoryGirl.create(:role_assignment, user: user, role: FactoryGirl.create(:role, name: "admin"))

I had been using FactoryGirl to create most of my test data even before this, but hadn’t realized before that FactoryGirl could be used even for data that would normally come from seeds.rb

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s