[Proposal] Accessor methods for preloaded fixtures

If fixtures are preloaded into the test database and transactional tests are used, fixture declarations (e.g. fixtures :all) may be omitted since all the data’s already there and every test case rolls back its changes. This reduces the load time for the test suite quite a bit, depending on how many fixtures exist.

However, without the fixture declarations, accessor methods are generated neither. Without those, fixtures are a lot less convenient to use.

My proposal is to generate accessor methods in this case as well. They could be derived solely from the file names of the fixtures, without loading and parsing them. The already existing option pre_loaded_fixtures, which is currently used only in combination with use_instantiated_fixtures, could be (re-)used to configure this new possibility.

The accessor methods generated for this configuration would have a few restrictions. First of all, they would only work if the fixture IDs are autogenerated. Because fixture files are not parsed, the ID must be computed in the accessor method with ActiveRecord::FixtureSet.identify and cannot be set manually in the YAML and mapped to the fixtures name. Also, the model class must correspond to the file name and cannot be changed with _fixture.model_class in the YAML file. Other restrictions might exist as well, possibly also with the new composite primary keys. If the option is not set, the current accessor methods should remain unchanged to prevent those restrictions.

Nevertheless, considering that autogenerated IDs are very widely used, I guess that a lot of projects currently using fixture accessor methods could benefit from the performance boost with preloaded fixtures.

I created a POC and employ this approach in a productive application. In a test application with 100 fixture files containing 3 records each, the test load time drops from 0.103 seconds to 0.013 seconds. In the mentioned productive application (with over a hundred fixture files), which is using a few gems that plug into ActiveRecord and influence the loading behavior, the test load time was reduced by about 3 seconds (because without parsing fixtures, models are not yet loaded with the suite, but only when used in the test cases).

In a further extension, a helper method maintain_test_fixtures! (à la maintain_test_schema!) could even check if the fixture files got modified since the last test run and re-load them if necessary to avoid stale data in the database.

What do you think? Is there a demand for such an option? Do you see other restrictions? Is this worth the added complexity of having two kinds of fixture accessor methods? I am eager to work on a pull request if this gets thumbs up here.

1 Like