Hi partypeople,
I'm currently implementing elasticsearch in our application and wanted to write tests. A clean and convenient way of doing this, is setting a seperate index prefix while testing[1]. This worked with Tire but is it also working with this gem? If not, what is your best practise to do this?
Another question: How do you all test with this gem in general?
:sparkling_heart: Thanks, :sparkling_heart:
b
what about having different servers for each environment ?
thanks for your reply, that would work but doesnt sound really convenient when developing locally on a simple machine?!
It works almost the same as with Tire -- you just define the correct index with the index_name method. So, you can do something like this in your test:
require 'test_helper'
class ArticlesControllerTest < ActionController::TestCase
setup do
Article.__elasticsearch__.index_name = 'articles_test'
Article.__elasticsearch__.import
Article.__elasticsearch__.refresh_index!
end
# ...
test "should get search results" do
get :search, q: 'mystring'
assert_response :success
assert_not_nil assigns(:articles)
assert_equal 2, assigns(:articles).size
end
end
Alternatively, you can set it up in the model, in the initializer, ... See the documentation for the index_name method: http://rubydoc.info/gems/elasticsearch-model/Elasticsearch/Model/Naming/ClassMethods#index_name-instance_method
Also, see the integration test here https://github.com/elasticsearch/elasticsearch-rails/blob/master/elasticsearch-model/test/integration/active_record_basic_test.rb
In general, make sure you play a bit with the Rails application templates: https://github.com/elasticsearch/elasticsearch-rails/tree/master/elasticsearch-rails#rails-application-templates
you can have 2 instances of elastic-search in the same machine, listening to different port.
Regarding different servers: not really needed for most cases. If you want to invest time into it, make sure you have a look at: https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-extensions#testcluster
I prefer to prefix the index name with the environment:
class User < ..
include Elasticsearch::Model
index_name "#{Rails.env}_users"
end
This way the index name for the User model would be test_users under the test environment. Preferably you could extract this to a module and use it in all your models with ElasticSearch functionality:
module Searchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
index_name [Rails.env, model_name.collection.gsub(/\//, '-')].join("_")
end
end
Yeah, I forgot to add the link to the Searchable module, which is part of the "expert" template, which does exactly that: https://github.com/elasticsearch/elasticsearch-rails/blob/master/elasticsearch-rails/lib/rails/templates/searchable.rb#L9
@pfeiffer , this is bad practice.
Let say you have a staging env that share the same indexes.
With your method, it won't be possible.
Why would you have a staging environment that shares data with your production or development environment? Talk about bad practice :-)
For example , when i update the User interface, i don't want to push it directly to the production. But i want to preview it with real data.
thanks! you are awesome! this helps me a lot. should I leave this ticket open for further discussions?
@benben I think we can close it -- I feel like both mine and @pfeiffer's suggestions are sufficient. I'll revisit the generated application tests, and maybe consider adding a specific chapter to the README about testing.
Ok, a chapter in the README would be awesome. Thanks!
Most helpful comment
I prefer to prefix the index name with the environment:
This way the index name for the User model would be
test_usersunder the test environment. Preferably you could extract this to a module and use it in all your models with ElasticSearch functionality: