I've been using Sunspot as my full-text search provider for a few months now. It's a very enjoyable library -- it hooks itself into Rails, provides an extension to disable itself in RSpec and even throws in a few convenient rake tasks. This fun came to a quick end, though, when I started delving into Cucumber again. Any feature involving finding a Sunspot-enabled item failed completely, but without any helpful errors. After a shameful amount of time banging my head against the desk, I finally got everyone to play nicely.
Let's just drop the code in and discuss it afterwards:
# config/sunspot.yml # copy the test settings into the cucumber environment test: &TEST solr: hostname: localhost port: 8981 log_level: WARNING cucumber: <<: *TEST # features/support/config.rb # start the Solr server and give it a few seconds to initialize Sunspot::Rails::Server.start sleep 5 # make sure that pickle calls #index! on our appropriate models require File.join(File.dirname(__FILE__), 'pickle') module Pickle module Session def create_model_with_sunspot(a_model_name, fields = nil) result = create_model_without_sunspot(a_model_name, fields) model = model(a_model_name) model.index! if model.respond_to?(:index!) result end alias_method_chain :create_model, :sunspot end end # clean out the Solr index after each scenario After do Post.remove_all_from_index! end # shut down the Solr server at_exit do Sunspot::Rails::Server.stop end
This method was heavily influenced by Brandon Keeper's post on using Cucumber with ThinkingSphinx. Thanks Brandon! So in my setup, I'm using Sunspot, Cucumber and Pickle (see Ryan Bates' railscast on using Pickle with Cucumber for more details on the wonderful Pickle gem).
First and foremost is getting the testing Solr server running. It will look for settings in
config/sunspot.yml according to the environment we're running in, so we need to duplicate the test environment for cucumber. I've found that it takes 3-5 seconds for Solr to properly spin up, so we're
sleeping for a few seconds to avoid the problem.
Next we need to ensure that each model gets loaded into Solr's index when created. If you're instantiating models on your own, this boils down to calling
#index! on any models that you create. Since I'm using Pickle (and didn't want to rework the included
pickle_steps.rb), I needed a bit more invasive measure. A bit of
alias_method_chain voodoo lets me call
#index! on every instantiated model that responds to it. This ensures that Pickle always adds it's models to Solr's index. I was pleased to find that I didn't have to disable transactional fixtures
Finally, we need to ensure that our index is fresh for each scenario, so we clear the Solr index out after each scenario is run. If you want a more targeted approach, you can use
# features/support/config.rb # clear Solr index only if we've actually used it After('@sunspot') do Post.remove_all_from_index! end
to only clear the Solr index after stories which are tagged with
@sunspot. Once all the stories are run, shut down the server. Viola!