Running cucumber features with sunspot_rails

February 3rd, 2010 by Patrick Baselier

We wanted to integrate the sunspot_rails gem into our cucumber features. I found a ticket where mat adviced to call Sunspot::Rails::Server.start / stop in one of the available cucumber hooks.

Code found in features/support/env.rb is run when Cucumber begins and exits so this seemed the right place to start Solr:

Sunspot::Rails::Server.new.start
 
at_exit do
  Sunspot::Rails::Server.new.stop
end

Also, make sure you’ve added a cucumber environment to the config/sunspot.yml file; we copied the test-environment for that:

test: &TEST
  solr:
    hostname: localhost
    port: 8981
    log_level: WARNING
 
cucumber:
  <<: *TEST

Running cucumber will let all scenarios fail unfortunately and we got a ‘Connection refused – connect(2) (RSolr::RequestError)‘ in our console.

The reason for this is simple (after I stepped into the sunspot_rails gem to be honest): the Sunspot::Rails::Server.new.start method will eventually launch a Java Servlet Container (Jetty) with the Solr WAR and uses the port defined in your sunspot.yml.
Now, starting up a server could take some time, so if cucumber’s features are run before the Solr server is up and running, the ‘Connection refused’ sounds trivial then.
First I added a sleep after starting up the server:

Sunspot::Rails::Server.new.start
sleep(5)

and this will work for most cases, but I thought it would be better to let cucumber wait just long enough until the server is up and running. When the server is up, you can open up your browser and enter http://localhost:8981/solr to administering Solr. This we can use to find out if we’ve waited long enough and start our features. I’ve put this into a seperate class named CukeSunspot and created this file in the features/support directory:

require "net/http"
 
class CukeSunspot
 
  def initialize
    @server = Sunspot::Rails::Server.new
  end
 
  def start
    @started = Time.now
    @server.start
    up
  end
 
  private
  def port
    @server.port
  end
 
  def uri
    "http://0.0.0.0:#{port}/solr/"
  end
 
  def up
    while starting
      puts "Sunspot server is starting..."
    end
    puts "Sunspot server took #{'%.2f' % (Time.now - @started)} sec. to get up and running. Let's cuke!"
  end
 
  def starting
    begin
      sleep(1)
      request = Net::HTTP.get_response(URI.parse(uri))
      false
    rescue Errno::ECONNREFUSED
      true
    end
  end
 
end

Now we can the alternative start method and remove the explicit sleep statement in our global before hook. features/support/env.rb:

CukeSunspot.new.start
 
at_exit do
  Sunspot::Rails::Server.new.stop
end

And voila, if you run cucumber, you scenario’s should run successfully. On my machine:

Sunspot server is starting...
Sunspot server is starting...
Sunspot server took 3.74 sec. to get up and running. Let's cuke!
Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • Hyves
  • Reddit
  • StumbleUpon
  • Twitter
  • Frank

    I’m sorry but I don’t see how you call your custom class. The last code at the bottom is calling the Sunspot class, not the CukeSunspot one so I don’t think your class will be used. Or did I miss something?

  • Patrick Baselier

    Thanks Frank, you’re absolutely right. I corrected the code.

  • http://www.milfont.org/tech/2010/06/23/setup-sunspot-e-rspec/ Setup do Sunspot-rails no Rspec – Milfont Consulting

    [...] nesse post, eu adaptei para o código que uso ao subir o sunspot com linha de comando para os testes de [...]

  • http://diminishing.org Michael Guterl

    I had been using this code for some time when all of a sudden I started running into issues with rspec running twice and it caused all kinds of chaos.

    I came across this thread: http://groups.google.com/group/rspec/browse_thread/thread/605d69f84c7e05ec but Andrew has not posted his monkeypatch, so I wrote one of my own.

    http://gist.github.com/511874

  • http://www.eet.nu/ Tom-Eric

    I’ve improved the code a bit so it will only start solr when the @search tag is first found. This speeds up running individual feature files without any negative consequences:

    http://gist.github.com/571576

  • http://upubly.publsh.com/2011/01/04/cucumber-spork-pickle/ Cucumber, spork, pickle « Upubly

    [...] my solr server to load every time I started my test environment and after a bit of searching found this blog post about auto starting solr for cucumber and rspec. You will need to require the class in your env.rb [...]

  • http://upubly.publsh.com/2011/01/07/testing-sunspot/ Testing sunspot « Upubly

    [...] first used this code and moved it into a lib/sunspot_starter.rb [...]

  • http://www.poseparquetflottant.fr Parquet flottant expert

    Hi there, thanks for the code I have been using for quite a while without any issues. Cheers!