Wednesday, June 24, 2009

Getting Ruby (Rails) Tests to Work When Forking with Spawn - Use Yield

Paul figured this one out. We had used Spawn to fork off a process that was taking a while and tests started failing. We tried just putting in stuff like:
sleep 5
But the issue wasn't that we had to wait on the forked process, but rather that when it forks, it is using new connections, new ActiveRecord instances, new ActiveMailer instances, etc.

In config/environments/test.rb we had:

Spawn::method :fork

We changed it to:

Spawn::method :yield
That way it won't fork the process. Here are a few pros and cons of this approach:
* Pros: Don't have to sleep so tests are less complicated and likely faster. Rails is not really setup with the intent that you'd be forking off stuff, so you are bound to run into a slew of issues in testing making it much more complicated. You can write tests faster if you don't have to worry about that complexity. (Ugh, I know. Not good.)
* Cons: You aren't testing things the way they are happening for real. This is a pretty big minus unfortunately. However, new development (and bug fixes) and the chance to possibly reduce the amount of time that is spent on the process that we had to fork, eliminating the need to fork, wins over time spent getting fork-friendly tests to work. When testing gets hard with no apparent benefit, "laziness" in testing often wins.

Hope that helps.

No comments: