测试在rspec中在一定时间内创建文件

时间:2015-03-12 00:13:46

标签: ruby asynchronous rspec

我有这个ruby项目,我生成一个进程。此过程在启动时会创建一个日志文件。

我很难测试这个。目前我开始这个过程,睡眠很短的时间(0.1秒)并检查文件是否已创建。

rspec测试看起来像这样:

describe 'the process' do
  it 'should create a log file' do
    start_the_process
    sleep 0.1
    expect('log-file.log').to exist
  end
end

这在我的机器上运行良好,但这个测试很不稳定。当它在CI上运行时,它会失败,因为该进程没有足够的时间来创建文件。 我可以增加时间。这将解决CI上的问题,但它会使测试变慢。

我真正想要测试的是该文件是在接下来的3秒内创建的。如果我睡3秒钟,测试将花费太多时间来运行。一种方法是检查文件是否存在于循环中,如果我们在接下来的3秒内没有看到该文件,则会失败。使用rspec似乎没有一种干净的方法。

3 个答案:

答案 0 :(得分:0)

我想也许你会从太高的水平上来。您应该测试日志记录类而不是进程。例如:

class Logger
  def initialize
    # create the log file
  end
end

然后你的规范:

describe Logger do
  let(:log_file_path) { 'log-file.log' }
  let(:subject) { described_class.new }
  it 'creates a log file on new' do
    subject
    expect( log_file_path ).to exist
  end
end

然后,您可以相信,当您的流程实例化新的Logger对象时,会创建日志文件。

答案 1 :(得分:0)

那么这个怎么样。

describe 'the process' do
  let(:sleep_time) { env is CI ? 3.0 : 0.1 }
  it 'should create a log file' do
    start_the_process
    sleep sleep_time
    expect('log-file.log').to exist
  end
end

答案 2 :(得分:-2)

通常在测试与时间相关的东西时,我们会留出时间来避免像你这样的问题,你可以这样做:

it "test" do
  time = Time.parse("Jan 01 2015")
  Time.stub!(:now).and_return(time)

  # your test, because now when you say 
  # Time.now, it will always returns 'Jan 01 2015'   
end

更新回答

我认为您可以使用相同的技术并覆盖规范中的sleep方法并返回0,这样就不会有等待。