Why I don’t use spork

Spork is great. And so is guard and its family of plugins. Early this year I spent a while converting all of my rails projects to use spork, and we even had a team standard tmux setup that ran spork in one of the start-up screens. So every time we saved a file, guard/spork ran some of our specs. We even had growl/notify pop up a little message telling us the result, so we didn’t have to go to the trouble of switching screen to find out. How very efficient!

But now I’ve turned spork off, and here’s why: Spork solves the wrong problem.

We enabled guard/spork because our specs were slow, and during the few months we had spork, those specs became even slower. But we never noticed. Most of the time guard/spork guessed correctly which specs to run, and we became quite good at configuring guard to re-load Rails when critical files changed. So we were reasonably comfortable, and our specs ran quickly most of the time. But our design was getting worse every day.

Slow specs are a sign of too much coupling, and in the case of a Rails app that usually means not enough separation between the domain objects and the adapters. So we’ve stopped running spork, so that we can feel the pain of the 15-second Rails load time, and so that we can feel the pain of all that coupling. And slowly we are making the app’s specs faster. Many spec files now run in under a hundredth of a second, and more will follow as we gradually peel domain code out from the Rails infrastructure. We don’t need to test the Rails components, and we have a very good suite of cucumber features that act as end-to-end integration tests. So our specs should be fast, and only need to tell us that our own objects each do their thing. That’s what we are now working towards, and that’s the pot of gold that spork was hiding from us.

8 thoughts on “Why I don’t use spork

  1. Kevin,

    Thanks for sharing this. I still don’t see how trimming 15 seconds or so from your test load can be a bad thing. How many times per day does that 15 second load happen?

    Could you not get the same gain by a rule like, you must run the tests without spork prior to a check in?

    I am asking all this because we are also looking at similar issues with slow tests and ways to speed them up and I have to say I was very pleased with spork saving us all that time and watchr kicking things off.


    • The 15 seconds we saved is the smallest part of the gain. Much bigger is that we now have less coupled objects. In fact, in order to make that gain I had to “discover” several Command objects that were hiding, masquerading as controller action method bodies. By pulling that code out into separate classes we can now test all of that code outside of the context of ActionController. Faster specs /and/ more expressive code!

  2. How does your test-speed correlate to rails startup-time? Even starting up a blank Rails 3 application for test is taking about 5 seconds on each rake call! (On a brand new iMac, don’t even think about doing it on a Air…)

    • @phoet — We’ve added a load more gems during the 7-8 months of developing this app, which all add to the startup time. And although we’ve sped up loads of specs, we still have all of that rails load time in most cases.

      Most of the speed-up we’ve achieved so far has been cutting the database out of spec runs by stubbing out various objects such as Warden.

      Longer term, the trick is to get more and more classes totally independent of rails, so their specs can be run without incurring that startup cost. We’ve only just begun down that road though…

      • One way to avoid this is to avoid Bundler’s “require by default” and change the line in config/boot.rb from `Bundler.require` to `Bundler.setup`.

        Once that is done, only require files/gems as you need them. (At the top of models, controllers, helpers, or in spec/support/whatever)

        Obviously when you run `rake` you’ll end up requiring them all anyway (if not you’re doing something wrong :P) so you won’t see gains there, but this will speed up running `rspec spec/some/file.rb:14` *so much* you’ll be happy.

        And as a side benefit, since things are lazily loaded in production, the first boot after a deploy will be much faster as well (which is a boon if you use passenger :))

  3. Pingback: A Smattering of Selenium #58 « Official Selenium Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s