SakuraWi - BLog

みんなのウェディングのエンジニア。聴いたお話をまとめておく倉庫的な。スタックストックスタック!

【Ruby on Rails】sidekiqをrspecでテストしてみよう


sidekiqを用いてバックグランドジョブをさばきたい人のための備忘録。 tips集みたいな感じで残します。

sidekiqって?

まずはやっぱドキュメントだ。本物をみよう。

https://github.com/mperham/sidekiq

バックグランドジョブを管理、実行するためのライブラリ。 非同期処理を使いたい時に便利です。

で、バックグランドジョブとか非同期処理って何?ってなるかと思うのでその解説を少しはさんでおきます。

通常動き続けているプロセスとは別に、この処理だけは別プロセス、スレッドでやってほしいってやつがありますよね。それを分けて処理してくれるのが非同期処理です。 誰かにメール飛ばす、なんてやつは独立した処理としてわけられるやつです。 イメージはメール飛ばすのは12時に別処理でやっておいてねーみたいな。

それをRuby on Railsでちゃちゃっと便利にやってくれるのがsidekiq。 ちなみに、activeJobというのもあります。

非同期処理ってなんやねんって思う人も一読するとよさそう。ちなみにめっちゃ高速で5分~10分くらいで読めちゃうので読んじゃいましょう。 Active Job の基礎 | Rails ガイド

sidekiqのジョブ

sidekiqのジョブはworkerと呼ばれます。 activejobとかだと、それを動かすためのスレッドがワーカなんていわれてちょっとややこしいなーと思いがち。

ということで、app/workersにこんな感じでファイルを作ります。

app/workers/test_worker.rb

class TestWorker
  include Sidekiq::Worker

  def perform(xxx, yyy)
    # 処理を書く
  end
end

だいたい、activejobと一緒ですね。

sidekiqのエンキュー

じゃ、ジョブを追加しましょう。

TestWorker.perfom_async(xxx,yyy)

これで追加できます。 activejobだと、.perform_laterとかでしたので、そこが違うポイントでしょうか。 .perform_inとかで時間指定のジョブにしたりもできます。

Rspecでテストしたろか

ほな、Rspecでのテストはどないですか、と。 これがまたちょっとやっぱいろいろ必要だったりするんですね。

sidekiqのrspec用のgemもあるようなので、必要によってはそっちを使ってもよさそうです。でも、なくてもテストできそうでした。

毎回のジョブをリセットする

spec/spec_helper.rb

...
config.before do
  Sidekiq::Queue.new.clear
end

これでテスト毎に生成されるジョブをリセットできます。

ジョブ数が追加されたことをチェックする

expect(Sidekiq::Queue.new.size).to eq 1

これでジョブが追加されて1になったかをチェック可能。

CircleCIでの設定

dockerを使っている場合は、

docker:
  - image: dedis:3.2

のように設定する必要がありそう。

まとめ

結構単純にジョブ追加、テストはできます。

ジョブ自体のテストは、中身の処理の各々のユニットテストをしっかり記述してテストすればよさそうです。