LoginSignup
18
14

More than 5 years have passed since last update.

RSpecのfeature specにElasticseachを組み込む

Last updated at Posted at 2014-09-06

Rails/RSpecでテストを書いていて、Elasticsearchを使った検索を盛り込んだテストを書く必要があったのでここにメモ。

動作環境:

  • Ruby: 2.1.2p95
  • Rails: 4.0.5
  • RSpec: 3.0.4
  • Elasticsearch: Version: 1.1.1

1) gem追加

これらのgemがないとそもそも無理っぽい

gem 'elasticsearch-rails'
gem 'elasticsearch-extensions'

2) spec_helper.rbにElasticsearchを使うときの処理を入れる

  • Elasticsearchは(確か)デフォルトで9200のポートを使うので、テストでは別のポートを割り当ててテスト用のElasticsearchサーバを立てるようにする。

  • 毎回Elasticsearchサーバが立ち上がるととても重たいので、elasticsearch: trueのメタタグをつけたブロックのみで有効になるようにしている

/spec/spec_helper.rb

require 'elasticsearch/extensions/test/cluster'

Elasticsearch::Model.client = Elasticsearch::Client.new(host: "localhost:9250")

# other configs

# elasticsearch config
config.before(:each, elasticsearch: true) do
  unless Elasticsearch::Extensions::Test::Cluster.running?(on: 9250)
    Elasticsearch::Extensions::Test::Cluster.start port: 9250, nodes: 1
  end
  User.__elasticsearch__.create_index! force: true
  User.__elasticsearch__.refresh_index!
end
at_exit do
  if Elasticsearch::Extensions::Test::Cluster.running?(on: 9250)
    Elasticsearch::Extensions::Test::Cluster.stop port: 9250
  end
end

3) モデルスペックに検索のテストを追加

  • あらかじめモデルのほうにはElasticsearchを使った検索時に:nameカラムがひっかかるようにしておく

  • 以下のように、Userモデルでは:nameカラムでの検索が有効になることをテストする

/spec/models/user_spec.rb

let(:user) { create(:user) }

describe ':search_matching_user', elasticsearch: true do
  before do
    user.__elasticsearch__.index_document
    Elasticsearch::Model.client.indices.flush
  end

  context 'nameで検索できる' do
    let(:user) { create(:user, name: "John Doe") }
    subject { User.search_match_customer_organizations("John").records.to_a }

    it { is_expected.to eq [user] }
  end
end

こんな感じ。

これでElasticsearchを使った検索を含むfeatureテストも書けるようになる。
Elasticseachを噛ませたテストが走る際、テスト用のElasticsearchサーバが毎回立ち上がるので実行には多少時間がかかるで、多用するとテストが遅くなる。

it 'ユーザを登録してそのユーザを検索する', js: true, elasticsearch: true do
  visit new_user_path
  fill_in 'user_name', with: 'Foo Bar'
  fill_in 'user_email', with: 'foo@bar.com'
  click_button 'Submit'

  expect(page).to have_content('Foo Bar')
  expect(page).to have_content('foo@bar.com')

  fill_in 'input_search', with: 'Foo'
  find_button('Search').click

  expect(find(".user_name")).to have_content('Foo Bar')
  expect(find(".user_emai")).to have_content('foo@bar.com')
end

ところで

Repro株式会社では一緒に切磋琢磨できる仲間を募集しています。 ぜひこちらをごらんください!

18
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
14