Fixtures Cleanup

All,

I've been playing a bit with some patches to make the fixture loading and management code a little bit easier to maintain. If I were to start chopping out features, how would you feel about losing:

Fixture instantiation,
Old school single-file fixtures,
CSV fixtures,
The ability to specify a subset of fixtures (everything's always loaded instead),
The ability to disable transactional fixtures,
or intrafixture ordering (OMap).

I'm not suggesting that any of these should necessarily disappear: I'm just interested in hearing what you think. Fire away.

~ j.

All,

I've been playing a bit with some patches to make the fixture loading
and management code a little bit easier to maintain. If I were to
start chopping out features, how would you feel about losing:

Fixture instantiation,

Never used, don't really care if that's gone.

Old school single-file fixtures,

Not sure what you mean here, is there some old-school fixture format
different from the usual tablename.yml fixtures or do you want to remove
the per-table yaml fixtures?

CSV fixtures,

Never used, but I could imagine those being useful to someone.

The ability to specify a subset of fixtures (everything's always
loaded instead),

I have always preferred loading all fixtures together because I like
using foreign keys which make it hard to only load some of the tables.

The ability to disable transactional fixtures,

I've always used transactional fixtures, but the problem is that right
now there are no nested transactions in rails which makes it hard to
test something that uses a transaction if the test itself is already
inside a transaction. I use a plugin, that allows nested transactions,
which should work with both postgresql and mysql but I don't think
all databases can even support nested transactions so removing the
ability to turn transactions off for some tests may not be a good idea.

or intrafixture ordering (OMap).

I've only used this a couple of times to be able to load fixtures for
a table that had a self-referential foreign key. Now that we have
the ability to load fixtures while ignoring foreign keys there does
not seem to be much value in ordered fixtures.

I'm not suggesting that any of these should necessarily disappear: I'm
just interested in hearing what you think. Fire away.

One thing that currently annoys me is that if you have a lot of fixture
data (in my case 4MB, a lot of small rows) it takes a couple of seconds
to load the data before the tests start. When just running all the tests
the time is not that long but when running just a single file it takes
more time to load the fixtures than it takes to run the tests.

When using autotest it becomes quite annoying to wait a couple of
seconds before each test run.

Since fixtures and database schema do not change that often it should
be possible to just load the fixtures once to the database and, if all
the tests run inside a transaction, on the next test run just load some
cache where only the fixture keys are held because technically that is
the only data that the database at that point does not already have.

Any ideas on the feasability of something like this?

Since fixtures and database schema do not change that often it should
be possible to just load the fixtures once to the database and, if all
the tests run inside a transaction, on the next test run just load some
cache where only the fixture keys are held because technically that is
the only data that the database at that point does not already have.

Any ideas on the feasability of something like this?

I like that idea. Since most people just run all tests inside a big
transaction anyway, there should rarely be changes to the fixtures or
the database. Keeping those stable when that's the case would be
great.

But we certainly should think about the transaction case. It's quite
valuable to be able to test transactions. So perhaps we can have a
special block or something that you could wrap around your test if it
uses transactions and make sure that all pre- and post-cleanup is
done. It'll make that one test run slowly, but that's fine.

I like that idea. Since most people just run all tests inside a big
transaction anyway, there should rarely be changes to the fixtures or
the database. Keeping those stable when that's the case would be
great.

The approach that's working for us really well right now:

1. Make a "fixtures or DB changed!" checksum and stash it. I'm using a sorted list of the full paths and mtimes of test/fixtures/**/*.yml, plus the mtime of schema.rb (since it's regenerated any time a migration runs).

1a. (there's a db:fixtures:reset task to kill this stash)

2. Regenerate and compare checksums on every test run. Different? Reload all fixtures: we're not specifying subsets anywhere. Same? No load necessary.

Preloading/change tracking like this has made autotest viable again, which has been pretty awesome.

But we certainly should think about the transaction case. It's quite
valuable to be able to test transactions. So perhaps we can have a
special block or something that you could wrap around your test if it
uses transactions and make sure that all pre- and post-cleanup is
done. It'll make that one test run slowly, but that's fine.

isolate_fixtures(:optional, :list, :of, :fixtures) do
   def test_something_involving_transactions
     # ...
   end
end

Something like that?

~ j.

The original fixtures format was one row per file. It's been deprecated in the docs for quite a while, but it's still around: See Fixture#read_fixture_file.

~ j.

Sounds like it should go then :wink:

I also never used them, but vote for keeping them because they make updating the fixture files with a spreadsheet application possible.

Thumbs up for everything else that has been tossed around.

I also never used them, but vote for keeping them because they make updating
the fixture files with a spreadsheet application possible.

Anyone here use them actively?

The few projects where I've used them / seen them used are better
served by the new foxy-fixtures stuff. habtm associations etc.

> I also never used them, but vote for keeping them because they make updating
> the fixture files with a spreadsheet application possible.

Anyone here use them actively?

The few projects where I've used them / seen them used are better
served by the new foxy-fixtures stuff. habtm associations etc.

I agree. Don't think we need to allow for multiple fixture formats.
Rather just focus on making the YAML ones the best they can be (the
foxy lift was great for that).

FWIW, the Globalize plugin uses CSV files for it's (substantial)
fixtures. It is much easier to read and scan 3000 columnar fixtures
than the equivalent YAML encoding.

For small volumes, I have no need for anything but YAML. For large
volumes, CSV is nice.

It seems to me that when a substantial amount of data is involved, it
would be quicker to make a backup database, and restore from it when a
change is detected during the tests. The other similar option would be
to use backup tables and a record of constraints--this would allow
single-table restorations.