Ok, so this app does have a lot of big fixtures but we’ve seen decent
gains on all our apps (typically 30-40%)
The long version:
fixtures are loaded once per testcase. If every single of your tests
names 0 or 1 fixtures than that’s fine. Back in the real world, customer
has_many :orders, :complaints, orders has_many :products etc… the
tests for all of orders, complaints, products, customer probably name
all those fixtures.
If a model uses another that isn’t named in the fixtures you can get
weird failures (because the table won’t have been cleared out and had
fresh data stuck in it prior to running the test, so for reasons of
maintainability we’ve ended up with all our fixtures in test_helper.
This of course means that if you have 50 unit tests, each one is being
loaded 50 times, i.e. 49 times too many. With some small caveats, this
plugin addresses this situation
Caveats:
this is an all or nothing thing: you can’t have it on for some
testcases, off for others
all of your fixtures must be named in test_helper
time stops (is stubbed out)i.e :
now = Time.now
get :index
assert Time.now > now
will fail. the point at which time stops is just before fixtures are
loaded
make sure all your fixtures must be named in test_helper
add require ‘faster_fixtures’ to your test_helper
Run tests and enjoy!
For another solution to this (but which means you can’t use the fixtures
accessors (eg foos(:first_foo) see this)
Thoughts, comments, suggestions etc… appreciated as usual. It works
great for all our apps, but I’d love to hear about it if it breaks yours
(and hopefully fix it )
I’ve just updated this to remove the requirement that all your fixtures
be in test_helper.rb. You can now declare them whenever, whereever you
want and my plugin just insures that any given fixture is not loaded
more that once.
I’d love to know if this works for other people (or indeed if it
doesn’t!)
I’ve just updated this to remove the requirement that all your fixtures
be in test_helper.rb. You can now declare them whenever, whereever you
want and my plugin just insures that any given fixture is not loaded
more that once.
I’d love to know if this works for other people (or indeed if it
doesn’t!)
Fred
Slick stuff – a test suite that ran in 50 seconds now runs in 28
seconds.
Once issue I’ve run across – I’ve got some unit tests in a
sub-directory under /test/unit/, and they aren’t able to access any
fixture data when I run the suite with faster_fixtures required. When I
run the tests individually, they can access fixture data just fine.
Slick stuff – a test suite that ran in 50 seconds now runs in 28
seconds.
Once issue I’ve run across – I’ve got some unit tests in a
sub-directory under /test/unit/, and they aren’t able to access any
fixture data when I run the suite with faster_fixtures required. When I
run the tests individually, they can access fixture data just fine.
I’ve tried to reproduce this but couldn’t. Could you give some more
details about your setup and the errors you’re getting ?
Thanks,
Fred
Fred,
Thanks for following up on this.
I created a fresh Rails app to try to reproduce this bug, but
(consistent with your findings) I wasn’t able to.
I did figure out a workaround – I’m using test/spec for my tests; when
I change the problem test (the one in a subdirectory of
RAILS_ROOT/test/unit) to standard test/unit style, it passes fine. Who
knows why.
My setup: Ruby 1.8.6, a recent version of edge Rails, with
test_spec_on_rails and fixture_references plugins (plus some other
common plugins that shouldn’t be interfering with testing.)
The problem is only with one particular record in one particular YAML
fixture file (which looks to be in fine YAML form) – I get
“ActiveRecord::RecordNotFound: Couldn’t find Location with ID=1” when I
run the suite, but when I run the individual test, it runs just fine.
When I check the db after I run the suite, I find three records in the
corresponding table; after I run the individual test, I see four.
And if I don’t require ‘faster_fixtures’ in my test.rb, I have no
problem.
So, who knows…?
Geoff
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.