title: Rails, be a pal and reset the database between test suites
body: <p>Work is transitioning from Rails 3 to Rails 4. Everything seems to be running more or less smoothly on the development side, but testing results in a multitude of varying failures when all suites - units, functionals, and integration - are run in one go with <code>rake:test</code>.</p>
  
  <p>What's interesting is that running each of these suites individually produces no failures. This strongly suggests that the database is not resetting for our tests in Rails 4 quite the way it was in Rails 3.</p>
  
  <p>I've tried overriding the rake:test task to execute <code>db:test:prepare</code> prior to running each suite, but this apparently doesn't do what I think it does, or rather, what I want it to do, which is to work with a fresh set of data for each test and therefore succeed or fail independently of every other test - the way it (was or should have been) in our Rails 3 setup.</p>
  
  <p>Why is this happening? How might I fix it?</p>
  
  <p>(Note that the testing framework is vanilla Rails with fixtures and the like. The testing failures we're getting are usually foreign key errors or failures for data to change in expected ways that don't show up when the DB is reset before a testing suite.)</p>
  
  <p>EDIT:</p>
  
  <p>Here are the changes I'm making to my Rakefile. The idea is to get rake:test to perform as it would in Rails 3, with the exception of properly resetting the database between unit, functional, and integration suites.</p>
  
  <pre><code># /Rakefile
  
  task :test =&gt; [];
  Rake::Task[:test].clear
  task :test do
      puts Rails.env
      if Rails.env == "test"
          puts "units"
          # Rake::Task["db:drop"].execute - results in 'test database not configured' error
          # Rake::Task["db:reset"].execute - results in 'relation 'table' does not exist' error
          Rake::Task["db:create"].execute
          Rake::Task["db:migrate"].execute
          Rake::Task["test:units"].execute
          puts "functionals"
          Rake::Task["db:schema:load"].execute
          Rake::Task["test:functionals"].execute
          puts "integration"
          Rake::Task["db:schema:load"].execute
          Rake::Task["test:integration"].execute
      end
  end
  </code></pre>
  
  <p>EDIT 2:</p>
  
  <p>Rails version 4.1.8</p>
  
  <p>Here is my test_helper. I've omitted helper methods that don't work with our data since I'm probably not allowed to share them and they're irrelevant to how the testing database is loaded.</p>
  
  <p>Note also that we have a custom schema.rb from which the testing data are generated, as well, since trying to create them from migrations does not support some of the custom functionality/behavior we want in the end product, like materialized views. Redacted stuff will be enclosed in &lt;&lt;>>.</p>
  
  <pre><code>#test_helper.rb
  ENV["RAILS_ENV"] = "test"
  require File.expand_path('../../config/environment', __FILE__)
  require 'rails/test_help'
  include ActionDispatch::TestProcess
  
  class ActiveSupport::TestCase
    # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
    #
    # Note: You'll currently still have to declare fixtures explicitly in integration tests
    # -- they do not yet inherit this setting
    set_fixture_class &lt;&lt;cached_object&gt;&gt;: ResultsDb::&lt;&lt;DesiredObjectClass&gt;&gt;Cache
    fixtures :all
  
    # Add more helper methods to be used by all tests here...
    def reload_contig(contig_sym)
      contig = contigs(contig_sym)
  
      src = contig.src
      new_tig = Contig.new(
                org: contig.org,
                version: contig.version,
                size: contig.size,
                sha1: contig.sha1,
                active: contig.active,
                src_id: src.id,
                src_type: contig.src_type)
  
      new_tig.id = contig.id
      contig.destroy
      unless new_tig.save
        raise new_tig.errors.full_messages.inspect
      end
      src.contigs &lt;&lt; new_tig
      src.save
      new_tig
    end
  
    def reload_coord(coord_sym)
        coord = coords(coord_sym)
  
        new_coord = Coord.new(
            :mapped_id =&gt; coord.mapped_id,
            :mapped_type =&gt; coord.mapped_type,
            :contig_id =&gt; coord.contig_id,
            :contig_type =&gt; coord.contig_type,
            :start =&gt; coord.start,
            :stop =&gt; coord.stop,
            :fwd_strand =&gt; coord.fwd_strand
        )
        new_coord.id = coord.id
        coord.destroy
        new_coord.save!
    end
  end
  </code></pre>