Elasticsearchを使ったテストを書くときにsleep 1するのはやめましょう

井原(@ihara2525)です。

以前RSpecでElasticsearchを使ったテストを書くというエントリの中で、

before do
  Post.__elasticsearch__.create_index! force: true
  Post.__elasticsearch__.refresh_index!
  page
  Post.import
  # Wait test cluster to index the created objects
  sleep 1
end

みたいなコードを書いていたのですが、いろいろと間違っていました。 まずimportがインデックスをつくってくれるので、

before
  Post.import
  # Wait test cluster to index the created objects
  sleep 1
do

でOK。 そしてsleep 1しているのはここにもあるように、Elasticsearchがインデキシングを1秒待つので、それが終わるまで、ということでした。

ただ、これだとタイミングによってインデックスが更新されておらず、テストが通ったり通らなかったりという辛い現象が発生してしまいます。

困っていたら漢方デスクのエンジニア@michi_omochiが対応策を調べてくれて、

before do
  Post.import
  Post.__elasticsearch__.refresh_index!
end

と、import後に即インデックスの更新を実行してあげれば解決しますと。素晴らしい。 さらに

before do
  Post.import(refresh: true)
end

refreshオプションを渡せばimportのみで同様のことが可能に。(この辺りの実装)

というわけで、sleep 1するのはやめて、refresh_idnex!を呼び出すか、import(refresh: true)として、明示的にインデックスを即更新してあげましょう。

これでインデキシングのタイミングでたまにテストがこける問題、無事解決しました。ありがとう、@michi_omochi