功能测试rake任务将输出添加到stdout。怎么避免这个?

时间:2015-08-31 15:31:05

标签: ruby rspec rake stdout

我尝试测试一个Rake Task并捕获其输出:

这是一个完整的集成测试(功能测试),它 意味着我想要端到端地测试它。所以我对顽固不感兴趣 拿出一些ConsoleRenderer类,只测试当我运行任务时,我 查看stdout中的某些输出。

实施,大大简化了

namespace :output do
  task :world do
    print 'hello world'
  end

  task :mars do
    print 'hello mars'
  end
end

功能测试(rspec 3.3):

require 'feature_helper'

describe 'some output' do
  before do
    Rails.application.load_tasks
  end

  after do
    Rake::Task['output:world'].reenable
    Rake::Task['output:mars'].reenable
  end

  it 'outputs' do
    expect { Rake::Task['output:world'].invoke }.to output('hello world').to_stdout
  end

  it 'outputs again' do
    expect { Rake::Task['output:world'].invoke }.to output('hello world').to_stdout
  end

  it 'outputs mars' do
    expect { Rake::Task['output:mars'].invoke }.to output('hello mars').to_stdout
  end
end

运行时,以某种方式累计过去运行的输出:

$ bundle exec rspec spec/features/output_spec.rb --order defined
.FF

Failures:

  1) some output outputs again
     Failure/Error: expect { Rake::Task['output:world'].invoke }.to output('hello world').to_stdout
       expected block to output "hello world" to stdout, but output "hello worldhello world"
     # ./spec/features/output_spec.rb:18:in `block (2 levels) in <top (required)>'

  2) some output outputs mars
     Failure/Error: expect { Rake::Task['output:mars'].invoke }.to output('hello mars').to_stdout
       expected block to output "hello mars" to stdout, but output "hello marshello marshello mars"
     # ./spec/features/output_spec.rb:22:in `block (2 levels) in <top (required)>'

为了说明,我按照定义的顺序运行测试。 第一次测试通过。第二个失败了,因为不知怎的,它包含了 在前一个测试中输出$stdout,或者自己运行两次。第三个相同(似乎自己运行三次)。

我怀疑这是Rake任务中的一部分,因为当我简化时 仅仅print的测试,这种添加不会发生:

it 'outputs' do
  expect { print 'hello world' }.to output('hello world').to_stdout
end

it 'outputs again' do
  expect { print 'hello world' }.to output('hello world').to_stdout
end

it 'outputs mars' do
  expect { print 'hello mars' }.to output('hello mars').to_stdout
end

这传递得很好。

请注意,在运行

的控制台上
Rake::Task['output:mars'].invoke
Rake::Task['output:mars'].reenable
Rake::Task['output:mars'].invoke

输出&#34;你好火星&#34;曾经,然后&#34;你好火星&#34;再次。问题不是 在这样的环境中重现自己。

我需要重置,重新启用,重新导入,截断或其他方式 改变,以便输出不加起来?

2 个答案:

答案 0 :(得分:1)

原来reenable不适合打电话。相反,我应该使用clear。它自己的文档是&#34;通常用于单元测试。&#34;。

after do
  Rake.application.clear
end

注意:这解决了这个问题,但我仍然不知道原因究竟是什么,也不知道问题中描述的设置如何在某个时刻运行任务三次。因此,解释为什么行为就像是为什么运行clear没有那样的答案将优先于我自己的答案。

答案 1 :(得分:0)

执行两次或三次的原因是因为您在每个块之前加载了任务:

before do
  Rails.application.load_tasks
end

代替使用before :all 并且可以选择在加载之前使用Rails.application.clear,因为如果您以其他规范加载了任务,它们仍然会存在