VisezTrance

  • October 7, 2013 11:55 PM

    From fixtures to factory girl

    By Daniel
    Inheriting a legacy application doesn't really have to be a chore. Bringing everything up to date is rewarding in its own way, although writing a ton of new tests isn't the most exciting thing around.

    Once everything was at a point we were comfortable with, we replaced the tightly coupled fixtures with Factory Girl. I knew there's a significant performance penalty to be paid, but it was rather shocking. At 20 minutes, the test suite took almost twice as long.

    I refactored some tests, mostly replacing FactoryGirl's create method with build_stubbed for non database operations but managed to shave off only two minutes.

    After some research, it looked like a user was created for every controller spec. There were legitimate cases, but most of the time this wasn't the case. So I ended up doing the following - a controller's current_user method gets stubbed by default, whereas if a current_user argument is passed it gets created as an AR object, for instance:

    it "does stuff", current_user: true do
      # doing stuff
    end

    The code responsible looked similar to the following:

    RSpec.configure do |config|
      config.before :each, type: :controller do
        user = if example.options[:current_user]
                 FactoryGirl.create(:user)
               else
                 FactoryGirl.build_stubbed(:user)
               end
        controller.stub(:current_user).and_return(user)
      end
    end

    The tests were faster at almost 12 minutes, but they still felt slow. Rspec's "--profile" flag didn't return any major offenders and just confirmed that most of the tests were just "slow". Trying to shave a few more seconds, I tried to use the same current_user approach to restrict search indexing.

    As we were using an acts_as_solr:

    RSpec.configure do |config|
      config.before :each do
        solr_models = [Model1, Model2, #..]
        solr_models.each do |model|
          if example.options[:search]
            ActsAsSolr::Post.execute(Solr::Request::Delete.new(:query => "type_t:#{model}"))
            model.configuration[:if] = true
          else
            model.configuration[:if] = false
          end
        end
      end
    end

    Not the cleanest implementation around, but it got the job done. The results were surprising to say the least. The tests took almost two and a half minutes, which is quite ok for over one thousand tests.

    Tags:

    • FactoryGirl,
    • Rspec
  • Monthly Archives

    • October 2013 (2)
    • May 2012 (1)
    • October 2011 (1)
    • September 2011 (2)
    • March 2011 (3)
    • February 2011 (1)
    • January 2011 (1)
    • September 2010 (1)
    • August 2010 (1)
    • June 2010 (1)
    • April 2010 (1)
    • December 2009 (1)
    • October 2009 (1)
    • September 2009 (1)
    • August 2009 (1)
    • July 2009 (2)
    • April 2009 (2)
    • February 2009 (1)
    • January 2009 (2)
    • December 2008 (1)
    • October 2008 (1)
  • Pages

    • About / Contact

2008, © Daniel Mircea