July 18th, 2008 - by Trevor
Long-as-hell Ruby on Rails RSpec test running times are making you ask “what the deuce?” Specs are taking way too long to run, but the prospect of looking through them all one at a time to find offending external dependencies, net calls that should be mocked, etc is driving you to drink. You just want a read-out of the tests that are taking the longest so you can refactor ASAP.
Sound familiar?
I was in this boat until I found out about the profiling command:
The double “spec” here can be a bit confusing. The first is the command, and the second is the directory (RAILS_ROOT/spec) that you’re running it on. The -f is the format flag. You can see a list of all formats with:
Basically you’re just passing the “profile” argument to the formatting command. It gives you a readout of the 10 most time-intensive specs at the top and then a nicely verbose list of all pending and failed tests. Using this list, I was able to go straight to the most obnoxious offenders and eliminate the external dependencies (these specs happened to be fetching feeds) that were slowing my test suite down. In less than 15 minutes, I had chopped my execution time down to 10% of what it was before I started.
Huzzah!
July 13th, 2008 - by Trevor
Setting up autotest earlier today was kind of an annoying, semi-humbling experience. A few things that people should know to save themselves some trouble:
- Everyone calls it autotest, but it’s actually ZenTest that you need to install. ZenTest is a larger testing package, of which autotest is merely one part.
- Autotest runs as a separate process (which you should background — the ‘&’ is your friend!) and watches your Rails dir after you have it turned on. This last bit took me some time to figure out, as the otherwise excellent RSpec Peepcode screencast completely glosses over this point. I kept waiting for the magic to happen when I hit “save” in TextMate, but I didn’t have the process running from the command line. Magic doesn’t work. I should stop expecting it to.
- Do yourself a favor and vastly simplify your autotest–>Growl connection by using Collin VanDyck’s GrowlGlue gem as the basis for your .autotest config file.
As of right now, I’m sitting here with just the basic GG config. I’m sure I’ll expand/customize tomorrow, but I’m just happy for now that I was able to get a working setup with just one line of code, as the normal way to get the connection going involves a decent amount of crap. After you get that going, GrowlGlue lets you set up all sorts of customization of the notifications — including custom messages, custom notification icons, and even speaking your test results through OS X’s built-in text-to-speech support — in nice, neat Ruby statements.
It’s nice to have something get in my face about my tests, and it’s also nice to have something that automatically makes you want to get your tests passing and running faster. Autotest provides you with the nagging voice that says “get your tests running right, holmes!” It’s good to strike this longstanding to-do off my list.
Late update: Turns out that running autotest in the background isn’t really ideal since you might sometimes want to cancel a running suite or check out the time elapsed since you started a given test set. What I’m looking for now is a way to see how long it takes any individual test to run so that I can find the offenders that are kicking up the aggregate time.