16 September 2008

Mocked by Default, but Unmocking in Some Cases with RSpec

Uh, ya, another great blog title, but we'll get over it. We use geocoding in our app, and that's a relatively costly operation time wise, especially when you may be doing it hundreds or thousands of times when your test suite runs. I can't stub out the objects that use it in many cases, so I wanted to stub out the actual geocode call unless I truly needed real geocoding (which is only when I'm testing the actual geocoding itself, and thus is a very small part of the test suite).

We use RSpec Specs and Stories and I wanted to mock out the geocoding by default, but unmock it in a few places. I asked about this on the mailing list, Googled and so on, but didn't find a solution that was working. So here is what I wound up doing...

In my spec_helper.rb file, I added:


Spec::Runner.configure do |config|
config.before(:each) do
# Setup fake geocoding unless told not to
unless @do_not_mock_geocoding
fake_geocode = OpenStruct.new(:lat => 123.456, :lng => 123.456, :success => true)
GeoKit::Geocoders::MultiGeocoder.stub!(:geocode).and_return(fake_geocode)
end
end
end


What this does is mock the geocoding unless a test has set the @do_not_mock_geocoding variable to true. One caveat, at least from what I've found, is that you need to set that to true in a before(:all) block in your tests, so that it happens before the before(:each). This is minor, as you can just have something like:

describe "with real geocoding" do
before(:all) do
@do_not_mock_geocoding = true
end

# your tests that want real geocoding
end


The impact this has had on our test suite is tremendous. I had already had some partial mocking of the geocoding in place, but was sweeping the system to put it in because the time it took to run our test suite was out of hand at about 13 minutes! Now that I've got this in, it runs in 2 minutes! Geocoding is used in two of our most core objects, which is why it has such a big impact on the test suite. This is one place mocking has really proved to be a massive value!

13 September 2008

Use the Lighthouse API for Mass Ticket Changes

Lighthouse is a nice issue tracker/bug database. We're using at at DealBase and some of my other projects. However, one thing it doesn't have, is a way to set the state of a bunch of tickets at once, or assign a slew of tickets to a certain user, etc. I need to do this regularly, as anytime we do a deploy to our staging environment, I need to go mark any bugs that were set to 'fixed' to now have a state of 'deployed', and then assign them to someone else to be verified. Lighthouse API to the rescue...

You can whip up a quick Ruby script to automate operations like this. The following is the script (tweaked to protect the innocent) I use to mark all tickets that are set to "fixed" to now be "deployed" and assign them to another user for verification. Obviously you can change this pretty easily to affect various other changes. I recommend playing with the Lighthouse API in IRB to see what the attribute names are for Tickets and so on.

02 September 2008

We're Hiring for a Rails or Similar Developer

The startup I work for, DealBase, is in need of another developer. This is pretty exciting for us, and the business is quite exciting as well! We're looking for someone with Rails experience, as well as MySQL, Git, TDD (BDD is good too), agile development practices, and so on. You can read all the details in our posting on the 37signals Gig Board. Please make sure you respond to the ad, as opposed to sending me email (or asking via a blog comment). You can mention in your email though that you found it via my blog entry.

One thing I want to specifically note, you don't have to be a "Rock Star"! Sure, we want the best people, but I too am sick of this "Rock Star" designation. I'd like to see someone who's passionate about software development, web apps, technology, TDD, JavaScript, and so on.

Another thing to note, we're a partially distributed team. I myself live in Eugene, Oregon, others are in the Bay area, one person Boston.