加快"睡眠"在Ruby中

时间:2014-09-12 08:01:26

标签: ruby testing rspec cucumber sleep

在我的代码中,我故意将许多地方放入“睡眠”,因为要求这些功能必须如此。但是,当我使用RSpec或Cucumber进行测试时,它会变得很麻烦,因为完成测试需要很长时间。

更新:感谢您的一些建议。然而,存根或手动重新定义可能是麻烦的。我想象的只是一个调整,以加快规模加速“睡眠”。

有这个宝石timecop。它可以通过比例加速Time.now。如果这种想法可以应用于睡眠,那就太棒了!

参考: https://github.com/travisjeffery/timecop


更新:抱歉迟到的回复,下面可能会说明我的情况:

class SomeClass
    def some_method
        sleep 15
        make_api_call_A
        sleep 45
        make_api_call_B
    end
end

describe SomeClass do
    before do
        Acceleration.speed_up(10) # speed time up to 10x
    end

    after do
        Acceleration.reset
    end

    if "should make two API calls" do
        subject.some_method
    end
end

正如您所看到的,some_method中有两个持续时间不同的睡眠。我更喜欢的是,如果我可以将睡眠时间加速到10倍,而不是等待60秒,我只需要等待6秒。这大大加强了测试过程。

4 个答案:

答案 0 :(得分:3)

您需要在规范中进行存根sleep调用。

class SomeClass
  def some_method
    sleep 10
  end
end

describe SomeClass do
  before do
    subject.stub!(:sleep)
  end

  it "should call sleep" do
    subject.should_receive(:sleep).with(10)
    subject.some_method
  end
end

答案 1 :(得分:2)

如果要缩放睡眠,可以这样覆盖Kernel.sleep方法:

module Acceleration
  mattr_accessor :sleep_scale

  def self.speed_up(scale)
    self.sleep_scale = scale
  end

  def self.reset
    self.sleep_scale = 1
  end

  reset
end

module Kernel
  alias :original_sleep :sleep

  def sleep(time)
    original_sleep(time / Acceleration.sleep_scale.to_f)
  end
end

class SomeClass
  def some_method
      sleep 15
      make_api_call_A
      sleep 45
      make_api_call_B
  end
end

describe SomeClass do
  before do
    Acceleration.speed_up(10) # speed time up to 10x
  end

  after do
    Acceleration.reset
  end

  it "should make two API calls" do
    subject.some_method
  end
end

答案 2 :(得分:1)

仅在测试时暂时添加以下内容。

def sleep *; end

答案 3 :(得分:0)

Monkey-Patch Kernel#sleep

假设您确实有一个有效的用例,并且您不想重构代码以避免硬编码的睡眠值或完全禁用睡眠,您可以简单地在其中修补Kernel#sleep您的规格使用缩放因子。例如,使睡眠运行速度提高十倍(例如,指定时间的1/10):

module Kernel
  alias_method :old_sleep, :sleep
  def sleep seconds
    old_sleep(seconds * 0.1)
  end  
end

基准缩放

一旦你进行了猴子修补睡眠,你可以测试你的缩放是否与Benchmark#realtime一起使用:

require 'benchmark'

Benchmark.realtime { sleep 10 }.round 2
#=> 1.0

Benchmark.realtime { sleep 0.1 }.round 2
#=> 0.01