43 votes

Comment tester ElasticSearch dans une application Rails (Rspec)

Je me demandais comment vous avez fait les tests de la recherche dans votre application lors de l'utilisation d'ElasticSearch et le Pneu.

  • Comment voulez vous créer un nouveau ElasticSearch instance de test? Est-il un moyen de s'en moquer?

  • Toutes les gemmes que vous savez de qui pourrait l'aider avec ça?


Quelques trucs que j'ai trouvé utile:

J'ai trouvé un grand article de répondre assez bien à toutes mes questions :)

http://bitsandbit.es/post/11295134047/unit-testing-with-tire-and-elastic-search#disqus_thread

De Plus, il n'y est une réponse de Karmi, Pneus d'auteur.

C'est utile aussi bien: https://github.com/karmi/tire/wiki/Integration-Testing-Rails-Models-with-Tire

Je ne peux pas croire que je n'ai pas trouvé ces avant de demander...

34voto

spaudanjo Points 540

La préfixation de votre index des noms pour l'environnement actuel

Vous pouvez définir un indice différent de nom pour chaque environnement (dans votre cas: l'environnement de test).

Par exemple, vous pouvez créer un initialiseur dans

config/initializers/tire.rb

avec la ligne suivante:

Tire::Model::Search.index_prefix "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}"

Un concevable approche pour la suppression de l'index

En supposant que vous avez des modèles nommé à la Clientèle, l'Ordre et le Produit, placez le code suivant sur votre test de démarrage/à l'avant-bloc/chaque-run-bloc.

# iterate over the model types
# there are also ways to fetch all model classes of the rails app automaticly, e.g.:
#   http://stackoverflow.com/questions/516579/is-there-a-way-to-get-a-collection-of-all-the-models-in-your-rails-app
[Customer, Order, Product].each do |klass|

  # make sure that the current model is using tire
  if klass.respond_to? :tire
    # delete the index for the current model
    klass.tire.index.delete

    # the mapping definition must get executed again. for that, we reload the model class.
    load File.expand_path("../../app/models/#{klass.name.downcase}.rb", __FILE__)

  end
end

Alternative

Une alternative pourrait être de créer un autre ElasticSearch instance pour tester sur un autre port, disons 1234. Dans votre environnement de test/.rb vous pouvez ensuite définir les

Tire::Configuration.url "http://localhost:1234"

Et à un endroit approprié (par exemple, votre test de démarrage), vous pouvez supprimer tous les index de la ElasticSearch test-exemple avec:

Tire::Configuration.client.delete(Tire::Configuration.url)

Peut-être que vous devez toujours vous assurer que vos Pneus sont-Cartographie des définitions pour votre modèle de classes sont encore appelés.

11voto

mhamrah Points 1240

J'ai couru dans une étrange bug lors de la suppression de mon index elasticsearch via pneu dans mon rspec suite. Dans mon Rspec de configuration, similaire pour les Bits et les Octets blog, j'ai un after_each appel qui nettoie la base de données et efface les index.

J'ai trouvé que je devais appeler un Pneu de create_elasticsearch_index méthode qui est responsable de la lecture de la cartographie dans le ActiveRecord classe pour définir le bon analyseurs, etc. La question que je voyais était j'ai eu quelques :not_analyzed champs dans mon modèle qui ont été réellement analysé (c'est la façon dont je voulais le facettage de travail).

Tout allait bien sur le dev, mais la suite de test n'était pas comme les facettes sont mis à mal par des mots et non pas l'ensemble de multi-parole de la chaîne. Il semble que la configuration de cartographie n'a pas été créé de manière appropriée dans rspec après l'indice a été supprimé. L'ajout de la create_elasticsearch_index appel fixe le problème:

config.after(:each) do
  DatabaseCleaner.clean
  Media.tire.index.delete
  Media.tire.create_elasticsearch_index
end

Media est mon modèle de classe.

4voto

Hengjie Points 1520

J'ai couru dans des problèmes similaires et voici comment je l'ai résolu. Bare à l'esprit que ma solution s'appuie sur @spaudanjo solution. Depuis que je suis en utilisant spork, j'ajoute ceci à l'intérieur de l' spec_helper.rbs' Spork.each_run bloc, mais vous pouvez ajouter ce dans n'importe quel autre chaque/avant le bloc.

# Define random prefix to prevent indexes from clashing
Tire::Model::Search.index_prefix "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}_#{rand(1000000)}"

# In order to know what all of the models are, we need to load all of them
Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
  load model
end

# Refresh Elastic Search indexes
# NOTE: relies on all app/models/**/*.rb to be loaded
models = ActiveRecord::Base.subclasses.collect { |type| type.name }.sort
models.each do |klass|
  # make sure that the current model is using tire
  if klass.respond_to? :tire
    # delete the index for the current model
    klass.tire.index.delete

    # the mapping definition must get executed again. for that, we reload the model class.
    load File.expand_path("../../app/models/#{klass.name.downcase}.rb", __FILE__)
  end
end

Essentiellement, il définit son propre préfixe unique pour chaque cas de test de sorte qu'il n'y a pas dans les index. Les autres solutions ont toutes souffert d'un problème où, même après la suppression de l'index, Elastic Search ne serait pas actualiser l'index (même après l'exécution de l' Model.index.refresh) c'est pourquoi l'étude randomisée préfixe est là.

Il charge également tous les modèles et vérifie si elle répond à l' tire , de sorte que nous n'avons plus besoin de maintenir une liste de tous les modèles qui répondent à des pneus à la fois, en spec_helper.rb et dans d'autres domaines.

Comme cette méthode ne prend pas de "supprimer" les indices après l'avoir utilisé, vous devrez supprimer manuellement sur une base régulière. Bien que je ne pense pas que ce soit un énorme problème, vous pouvez le supprimer avec la commande suivante:

curl -XDELETE 'http://localhost:9200/YOURRAILSNAMEHERE_test_*/'

Pour trouver ce YOURRAILSNAMEHERE , exécutez rails console et exécutez Rails.application.class.parent_name.downcase. La sortie sera le nom de votre projet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X