我尝试对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
输出一次“ hello mars”,然后再次输出“ hello mars”。这个问题不在这样的环境中进行自我复制。
我需要重设,重新启用,重新导入,截断或其他方式,变化,以使输出不累加?
结果是reenable
不合适。相反,我应该使用clear
。它自己的文档中的“通常在单元测试中使用。”。
clear
注意:可以解决此问题,但是我仍然不知道为什么确切地说以及问题中所述的设置在某个时候将任务运行了三次。因此,一个解释why行为的答案就像它的原样,而运行after do
Rake.application.clear
end
的why却没有,比我自己的答案更可取。
之所以执行两次或三次,是因为您在每个块之前加载了任务:
clear
而不是使用before do
Rails.application.load_tasks
end
并且可以选择在加载之前使用before :all
,因为如果您在其他规范中加载了任务,它们仍将存在]