Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would rails not reset the test database between runs

There are comments in the rails codebase that indicate that the test database should be reset between runs

rake -T

rake test:all                           # Run tests quickly by merging all types and not resetting db
rake test:all:db                        # Run tests quickly, but also reset db

config/database.yml

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:

This doesn''t seem to be the case for me.

I'm using factory girl generate test models, here is an example factory

FactoryGirl.define do
  factory :podcast do
    sequence(:title)     { |n| "Podcast #{n}" }
    sequence(:feed_url)  { |n| "http://podcast.com/#{n}" }
  end
end

The podcast should have a unique feed_url so I validate it's uniqueness in the model.

class Podcast < ActiveRecord::Base
  validates :feed_url, uniqueness: true, presence: true
end

In test_helper.rb I lint all factories

ENV["RAILS_ENV"] ||= "test"
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'minitest/autorun'

FactoryGirl.lint

My test creates a podcast, builds another with the same name, then asserts that the second is invalid.

require 'test_helper'

describe Podcast do
  describe '#feed_url' do
    it 'must be unique' do
      podcast = create(:podcast)
      new_podcast = build(:podcast, feed_url: podcast.name)

      assert_invalid podcast, :feed_url, 'has already been taken'
    end
  end
end

The first time I run the tests it executes without errors and the tests all pass. The second time I run the tests the Factory Girl lint fails because podcast feed_url has already been taken.

Why isn't the test database being rebuilt between runs?

like image 627
everett1992 Avatar asked Jun 12 '14 23:06

everett1992


1 Answers

We have a more involved FactoryGirl set up that prepares our database with some canonical items, but I think you could probably put this code directly in your test_helper.rb to assure the database is emptied:

# Destroy all models because they do not get destroyed automatically
(ActiveRecord::Base.connection.tables - %w{schema_migrations}).each do |table_name|
  ActiveRecord::Base.connection.execute "TRUNCATE TABLE #{table_name};"
end

Alternatively, run rake db:test:prepare before every run.

There is a gem too that you can use, but I don't have any experience with it: http://rubygems.org/gems/database_cleaner.

like image 186
rdnewman Avatar answered Nov 07 '22 10:11

rdnewman