我有一个红宝石项目,我在其中生成了一个进程。此过程在启动时创建日志文件。
我很难测试这个。目前,我开始该过程,睡眠一小段时间(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 做到这一点。
我想也许你从太高的水平来了。 您应该测试日志记录类而不是进程。 例如:
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
对象时,会创建日志文件。
那这个怎么样。
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
通常,在测试与时间相关的东西时,我们会存根时间以避免像您这样的问题,您可以执行以下操作:
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,这样就不会等待。