Ruby on Rails provides a convenient way to ensure consistent database state for all unit tests and this is accomplished through Fixtures.
In the Rails Weenie forums technoweenie presented a technique that allows us to ‘bootstrap’ our development or production database using the same underlying mechanisms.
The way it works is first we place YAML files similar to the ones we use for testing under
db/bootstrap (instead of
test/fixtures). Then it’s a simple matter of executing:
Fixtures and Referential Integrity
The only problem with the above technique is when your tables have foreign key constraints (as they easily could if you use ActiveRecord Migrations with my own Migrations Constraints Plug-in).
When using fixtures for unit tests, we can explicitly specify the order of the fixtures in code. For example:
fixtures :foo, :bar_references_foo
The original technique by technoweenie allows us to specify a fixture order by an environment variable:
FIXTURES="foo bar_references_foo" rake db:bootstrap:load
While it works, it requires us to specify our fixture names and their order every time – not very DRY if you ask me.
Sandro Paganotti on RailsOnWave.com also realized this and presented his own version of
rake db:bootstrap:load that attempts to address this.
The idea is to let us number our fixtures, similar to how we number our migrations, so that they can be loaded/unloaded in proper order according to our foreign key constraints.
Except, when I looked more closely at his code, I had my reservations.
First, and most glaring, is that he sorts the fixtures array, even if it’s passed in through the
FIXTURES environment variable. I think this totally defeats the purpose of explicitly specifying the fixtures that way.
Second, and relatively minor, is that he hard-codes the format of the fixture file names so they have to be 2 digit numbers followed by an underscore, then the table name.
So I set about to write my own, slightly more evolved version of Sandro Paganotti’s rake task.