加速Ruby中的“睡眠”

fsi0uk1n  于 2023-04-29  发布在  Ruby
关注(0)|答案(5)|浏览(193)

在我的代码中,有很多地方我故意放在“睡眠”,只是因为功能是要求的。然而,当我使用RSpec或Cucumber进行测试时,它就变得令人讨厌了,因为完成测试需要很长时间。
更新:谢谢你的一些建议。然而,存根或手动重新定义可能会很麻烦。我想象的只是一个调整电话,以加快“睡眠”与一个规模。
有一个宝石时间表。它可以加速 www.example.com 梳理如果这种想法可以应用到睡眠中,那就太好了!
参考: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中有两个不同持续时间的sleep。我更喜欢的是,而不是等待60 s,如果我可以加快睡眠时间到10倍,我只需要等待6s。这大大加快了测试过程。

ogsagwnx

ogsagwnx1#

在规范中需要stub 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
ycggw6v2

ycggw6v22#

如果你想扩展sleep,你可以用这种方式覆盖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
wpcxdonn

wpcxdonn3#

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

def sleep *; end
pgx2nnw8

pgx2nnw84#

Monkey-Patch内核#sleep

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

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

对标您的伸缩

一旦你完成了monkey-patched sleep,你就可以使用Benchmark#realtime测试你的扩展是否有效:

require 'benchmark'

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

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

xxe27gdn5#

在我看来,有一个解决方案更容易,并且不会给你的项目增加更多的依赖:
在类中,将睡眠时间放入常量,例如:

WAITING_TIME = 45

使用此常量而不是数字调用sleep

sleep WAITING_TIME

在测试中,使用RSpec中的stub_const更改睡眠时间:

before do
  stub_const('MyClass::WAITING_TIME', 4.5)
end

就这些您不需要模拟sleep调用,也不需要额外的gem,RSpec将负责清除常量并在测试结束时将其重置。

相关问题