Tracking Down Missing Fixtures

Posted by Rick DeNatale Tue, 17 Jul 2007 17:50:00 GMT

The other day I wrote about problems with undeclared fixtures in Rails ActiveRecord tests.

Here’s a little code snippet which might be useful in tracking down such problems.

class MyTest < Test::Unit::TestCase

  def self.been_here
    result = @been_here
    @been_here = true
     result
   end

  class RowCounter < ActiveRecord::Base
  end

  def setup
    unless self.class.been_here
      File.open("#{RAILS_ROOT}/data_dump_#{Time.now.strftime("%m%d%H%M%S")}", "w") do |file|
        Account.connection.tables.each do |table_name|
          RowCounter.table_name = table_name
          file.puts "#{table_name}:  #{RowCounter.count}"
        end
      end
    end
    # The rest of your setup code goes here
  end

# And the rest of the TestCase code here
end

This will dump a list of each table with a count of its rows the first time setup is run for the testcase. The file name is generated with a time stamp

Okay, so the example does go along with this weeks Harry Potter fever.

rails_developer@hogwarts.edu.magic.uk/cauldron_project/trunk$ cat data_dump_0717105533
students:  17
professors:  2
owls:  2
potions:  2
magical_creatures:  2
muggles:  0

Now you can run the test individually and then along with others. Then use a diff tool to see which tables have different numbers of rows before your test case starts for the first time.

A test helper

If you find this useful, why not add it to a test helper. If you don’t already have one, edit your test/test_helper.rb file, and add the following code inside of the Test::Unit::Testcase class:

  def self.been_here
    result = @been_here
    @been_here = true
    result
  end

  class RowCounter < ActiveRecord::Base
  end

  def dump_table_counts(file_name)
    File.open(file_name, "w") do |file|
      Account.connection.tables.each do |table_name|
        RowCounter.table_name = table_name
        file.puts "#{table_name}:  #{RowCounter.count}"
      end
    end
  end

I’ve moved the definition of the been_here method and the class Rowcounter from the individual testcase to the superclass. The only code in the testcase needed to use this is in the setup method, which now becomes:

  def setup
    dump_table_counts("#{RAILS_ROOT}/data_dump_#{Time.now.strftime("%m%d%H%M%S")}") unless self.class.been_here

    # rest of setup code here
  end

Trackbacks

Use the following link to trackback from your own site:
http://talklikeaduck.denhaven2.com/trackbacks?article_id=443