浩文 联系 关于本站 登录 注册
  • 关注新浪微博:
  • 关注微信公众号:

Sidekiq Github wiki 中文文档

测试

commit信息:More details about using server middleware in tests | 提交者:ajw725 | 提交时间:2019-10-19 | 版本:dab35d7

Sidekiq给测试workers提供了一些选项。

设定

Sidekiq提供了以下三种测试模式:

Sidekiq允许你使用下面方法动态配置测试工具:

require 'sidekiq/testing' 
Sidekiq::Testing.fake! # fake is the default mode
Sidekiq::Testing.inline!
Sidekiq::Testing.disable!

警告: 请求sidekiq/testing会自动调用 Sidekiq::Testing.fake!
因此你的作业将不会到达Redis。不要在任何生产代码中请求sidekiq/testing

以上的每个方法都可以接收一个block。
一个例子:

require 'sidekiq/testing'
Sidekiq::Testing.fake!

# Some tests

Sidekiq::Testing.inline! do
  # Some other tests
end

# Here we're back to fake testing again.

要查询当前状态,请使用以下方法:

Sidekiq::Testing.enabled?
Sidekiq::Testing.disabled?
Sidekiq::Testing.fake?
Sidekiq::Testing.inline?

Testing Worker Queueing (Fake)

ActionMailer测试API相似,代替把作业推送给Redis,sidekiq把它们推送给你可获取的jobs组数。在你的{test,spec}_helper.rb文件中请求sidekiq/testing文件,然后设置该模式:

require 'sidekiq/testing'
Sidekiq::Testing.fake!

然后断言这些作业会被推送到该队列:

expect {
  HardWorker.perform_async(1, 2)
}.to change(HardWorker.jobs, :size).by(1)
assert_equal 0, HardWorker.jobs.size
HardWorker.perform_async(1, 2)
assert_equal 1, HardWorker.jobs.size

你可以通过清空该队列来执行所有排队的作业:

HardWorker.perform_async(1, 2)
HardWorker.perform_async(2, 3)
assert_equal 2, HardWorker.jobs.size
HardWorker.drain
assert_equal 0, HardWorker.jobs.size

用来执行所有workers排队的作业:

Sidekiq::Worker.drain_all

如果你不想在移除一些作业前实际执行它们:

HardWorker.perform_async(1, 2)
HardWorker.clear
assert_equal 0, HardWorker.jobs.size

清除所有workers的作业:

Sidekiq::Worker.clear_all

下面代码用来确保作业不会在测试之间徘徊:

RSpec.configure do |config|
  config.before(:each) do
    Sidekiq::Worker.clear_all
  end
end
module SidekiqMinitestSupport
  def after_teardown
    Sidekiq::Worker.clear_all
    super
  end
end

class MiniTest::Spec
  include SidekiqMinitestSupport
end

class MiniTest::Unit::TestCase
  include SidekiqMinitestSupport
end

队列API(4.0+)

在4.0+版本上有一个有效的队列测试API。当被测试的应用程序中不存在Worker类时,这将很有帮助。一个使用Sidekiq::Client来入队的作业:

Sidekiq::Client.push(
  'class' => 'NonExistentWorker',
  'queue' => 'other',
  'args' => [1]
)

由于应用中没有NonExistentWorker,我们可以确定是作业给队列制造的该问题:

assert_equal 0, Sidekiq::Queues["other"].size

Sidekiq::Client.push(
  'class' => 'NonExistentWorker',
  'queue' => 'other',
  'args' => [1]
)

assert_equal 1, Sidekiq::Queues["other"].size
assert_equal "NonExistentWorker", Sidekiq::Queues["other"].first["class"]

# Clear an individual queue
Sidekiq::Queues["other"].clear

# Clear all queues (equivalent to Sidekiq::Worker.clear_all)
Sidekiq::Queues.clear_all

直接测试Workers

直接测试你的worker,就像对待ruby对象一样对待它。这很简单!

work = HardWorker.new
work.perform(1, 2)

内联测试Workers

通过在你的{test,spec}_helper.rb文件中请求sidekiq/testing文件,并且设置inline模式,可以在你的测试中内联运行Sidekiq workers。

require 'sidekiq/testing'
Sidekiq::Testing.inline!

# 或者使用块模式,这样能阻止泄露设置信息到其它的测试
Sidekiq::Testing.inline! do
  HardWorker.perform_async
  assert_worked_hard
end

当作业被放入该队列后,它们会被立即执行。

测试delay和delay_for方法

你可以从Sidekiq::Extensions::DelayedMailer (ActionMailer), Sidekiq::Extensions::DelayedModel (ActiveRecord), 或者 Sidekiq::Extensions::DelayedClass (其它的)轻松地获取到作业的队列。

assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
MyMailer.delay.send_welcome_email('foo@example.com')
assert_equal 1, Sidekiq::Extensions::DelayedMailer.jobs.size

测试Server中间件

默认,测试工具(每个模式中)不会运行任何的server端中间件。使用下面代码,你可以把中间件添加到其中:

Sidekiq::Testing.server_middleware do |chain|
  chain.add AwesomeMiddleware
end

Sidekiq::Testing.server_middleware栈中的中间件在inline模式里每当作业被运行它就会被运行,在fake模式中,每当.drain 或者 .perform_one被调用时会被运行。

注意,如果你的中间件位于lib/sidekiq/middleware/server/awesome_middleware.rb文件中,根据这里的描述,你将需要请求chain.add Sidekiq::Middleware::Server::AwesomeMiddleware类,并且像下面这样定义它以便它能正确地加载到测试链中:

module Sidekiq::Middleware::Server
  class AwesomeMiddleware
    # do stuff
  end
end

class Sidekiq::Middleware::Server::AwesomeMiddleware这样定义一个类在测试环境中将不能正确起作用,因为Sidekiq::Middleware::Server不会被自动加载。你必须明确地请求中间件文件。

API

Sidekiq的API没有测试模式,也就是说,就像Sidekiq::ScheduledSet.new.each(...)将总是命中Redis。你可以使用Sidekiq::Testing.disable!来设置作业,以便在你的测试中对着一个真实地Redis实例使用该API。

测试Batches

Batches在许多作业之间高度地集成。在测试时,最终运行整个batch实现很困难:我建议手动触发回调而不是试着设置batch中间件。

Sidekiq::Testing.inline! do
  b = Sidekiq::Batch.new
  b.on(:success, SomeCallback)
  b.jobs do
    # inline will perform jobs immediately
    5.times { HardWorker.perform_async }
  end
  # fire callback manually
  SomeCallback.new.on_success(nil, nil)
end

RSpec

请查看rspec-sidekiq gem.

后台并发运行Capybara 功能测试

出自 https://makandracards.com/makandra/28125-perform-sidekiq-jobs-immediately-in-development

# config/environment/test.rb

# perform jobs immediately
config.active_job.queue_adapter = :sidekiq
require 'sidekiq/testing'
Sidekiq::Testing.inline!
...

上一篇: FAQ 下一篇: 分片