I try to feature test a Rake Task and capture its output:
This is a full integration test (feature test), which
means I want to test it end-to-end. So I am not interested in stubbing
out some ConsoleRenderer class, just testing that when I run the task, I
see certain output in stdout
.
The implementation, greatly simplified is
namespace :output do
task :world do
print 'hello world'
end
task :mars do
print 'hello mars'
end
end
And the feature test (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
When running this, somehow the output of the past runs is added up:
$ 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)>'
To illustrate, I run the test in order of definition.
The first test passes. The second fails, because somehow it includes the
output of the $stdout
in the previous test, or runs itself twice. Same for the third (which seems to run itself thrice).
I suspect this is something in the Rake task, because when I simplify
the tests to merely print
something, this adding does not occur:
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
This passes just fine.
Note that, on a console running
Rake::Task['output:mars'].invoke
Rake::Task['output:mars'].reenable
Rake::Task['output:mars'].invoke
Outputs "hello mars" once, then "hello mars" again. The issue does not reproduce itself in such an environment.
What do I need to reset, reenable, re-import, truncate or otherwise change, so that the output is not adding up?