The ELC Community Blog
A knowledge exchange on Ruby on Rails and Agile Development
Preloading fixtures
by stevend on May 31, 2007
Ever wonder why it takes so gosh darn long to run your tests?
Do you hate it when forgetting to load a valuable fixture breaks your test?In my experience, long test times are due to two reasons: fixture loading and fixture instantiation
If you don't use instantiated fixtures such as @users_one, and instead use users(:one), then you can safely turn off instantiated fixtures, saving you all the time of finding the data. But what about fixture load time? If you use transactional fixtures, the loading only takes place once per test file, which could be 100-150 times in a given project. Without transactional fixtures, they are loaded before every test, clearly a waste of time!
My solution was to develop a plugin which proloads and preinstantiates the fixtures only once (well, 3 times was the best I could get). It takes advantage of transactions to rollback the state of the database between each individual test (don't try this on MySQL with bad storage engines like MyIASM, kids). It usually takes a few seconds, of course, but cut a down "rake test" for a large project of ours from 20 minutes to 90 seconds. Plus, you don't have to remember which fixtures you need for every single test file anymore! Try adding the globalization plugin, for example, and you'll realize you need 2 fixtures on every single page.
In my opinion, there's no reason not to preload all your fixtures once before running tests, but that's up to you to decide.
Plugin Usage
- Install the plugin
- Add the following to test/test_helper.rb
1 <pre> PreloadFixtures.preload! 2 PreloadFixtures.instantiate!(Test::Unit::TestCase)</pre>
- The "fixtures" function in a test is now overloaded to do nothing. All fixtures in the directory will be loaded once and then the tests will be run.
Download Plugin
From our svn respository
1 <pre>./script/plugin install https://wush.net/svn/public/preload_fixtures</pre>
Timeline
- Migrate Test DB Rake Plugin
- FunnyOrDie.com in Time's 50 Best Websites of 2007
- TuneCore and Public Enemy in New York Times
- Conditional Action Caching with Cache_Fu
- SSH Configuring RightScale's RightImage FC6V2
- Preloading fixtures
- Using and testing multiple databases in rails part 2
- RailsConf Europe
- Why associated models don't save
- RailsConf 2007 Highlights
- RailsConf 2007 - Day 1
Comments
I can’t install the plugin:
andraskristof$ ./script/plugin install https://wush.net/svn/public/preload_fixtures
/usr/local/lib/ruby/1.8/net/http.rb:586:in `connect’: certificate verify failed (OpenSSL::SSL::SSLError)
Is this just me, or a general problem?
I have abandoned fixtures altogether and just explicitly create (or mock with Mocha) the required records in the tests that need them. This works great and the tests run lightning fast!
Sorry for the install problems. The code is all there at https://wush.net/svn/public/preload_fixtures, so I’m not sure why it wouldn’t work!