Ruby on Rails
HowToUseFixturesMoreEfficiently

How To Use Fixtures More Efficiently

You’re using fixtures, and testing, and everything is fine. But if you’re like me, your database has loads of relational constraints, so you can’t just load one fixture independent of others. And if you’re not using relational constraints, you should be.

So, what happens is that the top of every test has some great list of fixtures like this:


fixtures :foo, :bar:, wibble, :ping, :boink, :dropsy

And you eventually end up with almost the same list in ever test case. Not very DRY, right?

Easy, you think. You add the list of fixtures to test_helper.rb and all is good with the world. You only need to maintain it in one place.

And then you start integration testing, and it all falls apart.

How to fixture Integration Tests by peter.fitzgibbons

Actually, in order to fixture all integration tests, use the same device as Test::Unit like this :


class ActionController::IntegrationTest

  #fixtures that will be required on EVERY unit/functional/integration test.
  fixtures :permissions, :roles, :permissions_roles, :users, :users_roles

end

Another Way to Make All Fixtures Available in Your Tests

Put this in your test/test_helper.rb file (at the end):


def all_fixtures
  fixtures = []
  Dir["#{RAILS_ROOT}/test/fixtures/*.yml"].each do |path|
    filename = path.gsub('.yml', '').split('/').last
    fixtures << filename.to_sym
  end
  return fixtures
end
</pre>

Then say for example in your test/unit/user_test.rb just add:


class UserTest < Test::Unit::TestCase
  fixtures all_fixtures
  ...
</pre>

The old way…

Because, due to all sorts of load ordering stuff, for integration tests the fixture loading code isn’t loaded when test_helper is. And it’s really hard to fix that.

So, what you need to do is this:

In test_helper.rb, add a module that loads the fixtures for you, like this:


module DRYFixtureLoader
  def self.included(base) #:nodoc:
    base.class_eval do
      fixtures :foo, :bar:, wibble, :ping, :boink, :dropsy
    end
  end
end

Then include DRYFixtureLoader in the Test::Unit::TestCase subclass defined in that file, and in all your integration tests.

It’s hacky, but it works.

Simon