How to test ElasticSearch in a Rails application

How to test ElasticSearch in a Rails application

Since I started using ElasticSearch in my Rails applications, I had a problem to create separate indexes for the automated tests.

The problem is: there is no way to create more than one database in ElasticSearch. You can create different indexes, but no different databases. But creating indexes with different names doesn’t solve the problem: it’s necessary to configure our Rails models in order to work with a different index name when the tests is running.

I’m using the tire and RSpec gems and in this post, I’ll explain how to separate indexes for development and test environments.

First of all, I’ve included the code below in file config/initializers/tire.rb:

if Rails.env.test?
  prefix = "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}_"
  Tire::Model::Search.index_prefix(prefix)
end

And I set manually the index name in the model (assuming that there is a Movie model):

index_name "#{Tire::Model::Search.index_prefix}movies"

Done! After that, when your application is running in development environment, the name of indexes will be “movies”. But if it’s in the test environment, the name of indexes will be “appname_test_movies” and then the tire gem and your models can perform the search with different indexes!

Deleting test indexes

In order to delete the test indexes after the suite has finished running, just add the following code to file spec/integration_helper.rb (or similar):

RSpec.configure do |config|
  config.after(:all, type: :request) { delete_movie_index }
end

And create a custom macro, which will delete the indexes:

def delete_movie_index
  Movie.index.delete
end

Demo app

I created a small application to demonstrate the technique explained in this post:
https://github.com/lucascaton/elasticsearch_app_example

I hope this has been helpful!

  • rip van winkle

    Good answers in return of this matter with firm arguments and
    explaining all on the topic of that.

    Also visit my web blog … rip van winkle

  • Jay

    Hi!

    Thanks for the great post! It saved me today :)

    I am completely with you on the Initalizer (tire.rb) and defining the index_name in the Model.
    But is an own integration_helper.rb necessary?

    I just added

    config.after(:suite) do
    # Drop Index stuff
    end

    into my spec_helper.rb

    Works like a charm.

    Best
    Jay

  • Hi Jay.

    The integration_helper file is not necessary. I wrote in the post “or similar”! :-)

  • Pingback: Elasticsearch and RSpec integration | Technology & Programming Answers()

Comments are closed.