| 
         
           Peter Marklund's Home | 
      
Rails Testing Tip: Validate your Fixtures
I realized today how important it can be to validate the fixtures you use in your Test::Unit tests or RSpec specifications. I made some schema and validation changes and neglected to update all my fixtures which lead to a long and tedious debugging session. I added this RSpec specification to make sure I never have invalid fixtures again:
describe "fixtures" do
  it "should be valid" do
    ActiveRecord::Base.fixture_tables.each do |table_name|
      klass = table_name.to_s.classify.constantize
      klass.send(:find, :all).each do |object|
        puts("  is invalid: ") if !object.valid?
        object.should be_valid
      end
    end
  end
end
Note: the fixtures_tables method is just a method I have defined that returns a list of all my fixture tables and I use it to set global fixtures in my test_helper.rb and spec_helper.rb files. If you are not using global fixtures, you can use this spec instead:
describe "fixtures" do
  it "should be valid" do
    Fixtures.create_fixtures(fixture_path, all_fixture_tables)
    all_fixture_tables.each do |table_name|
      begin
        klass = table_name.to_s.classify.constantize
        klass.send(:find, :all).each do |object|
          puts("  is invalid: ") if !object.valid?
          object.should be_valid
        end
      rescue NameError
        # Probably a has and belongs to many mapping table with no ActiveRecord model
      end
    end
  end
  
    Spec::Runner.configuration.fixture_path
  end
  
    Dir[File.join(fixture_path, "*.yml")].map {|file| File.basename(file[/^(.+)\.[^.]+?$/, 1]) }    
  end
end
I think it would be nice if Rails/RSpec has fixture validation built in and turned on by default.