Skip to main content

output matcher

The output matcher provides a way to assert that the block has emitted content to either $stdout or $stderr.

With no arg, passes if the block outputs to_stdout or to_stderr. With a string, passes if the blocks outputs that specific string to_stdout or to_stderr. With a regexp or matcher, passes if the blocks outputs a string to_stdout or to_stderr that matches.

Note: to_stdout and to_stderr work by temporarily replacing $stdout or $stderr, so they're not able to intercept stream output that explicitly uses STDOUT/STDERR or that uses a reference to $stdout/$stderr that was stored before the matcher is used.

To capture output from any spawned subprocess as well, use to_stdout_from_any_process or to_stderr_from_any_process. Output from any process that inherits the main process's corresponding standard stream will be captured.

Note: to_stdout_from_any_process and to_stderr_from_any_process use tempfiles to capture output, and are thus significantly (~30x) slower than to_stdout and to_stderr.

Using the output_to_stdout matcher

Given a file named "output_to_stdout_spec.rb" with:

RSpec.describe "output.to_stdout matcher" do
specify { expect { print('foo') }.to output.to_stdout }
specify { expect { print('foo') }.to output('foo').to_stdout }
specify { expect { print('foo') }.to output(/foo/).to_stdout }
specify { expect { }.to_not output.to_stdout }
specify { expect { print('foo') }.to_not output('bar').to_stdout }
specify { expect { print('foo') }.to_not output(/bar/).to_stdout }

# deliberate failures
specify { expect { }.to output.to_stdout }
specify { expect { }.to output('foo').to_stdout }
specify { expect { print('foo') }.to_not output.to_stdout }
specify { expect { print('foo') }.to output('bar').to_stdout }
specify { expect { print('foo') }.to output(/bar/).to_stdout }
end

When I run rspec output_to_stdout_spec.rb

Then the output should contain all of these:

| 11 examples, 5 failures | | expected block to output to stdout, but did not | | expected block to not output to stdout, but output "foo" | | expected block to output "bar" to stdout, but output "foo" | | expected block to output "foo" to stdout, but output nothing | | expected block to output /bar/ to stdout, but output "foo" |

Using the output_to_stderr matcher

Given a file named "output_to_stderr.rb" with:

RSpec.describe "output_to_stderr matcher" do
specify { expect { warn('foo') }.to output.to_stderr }
specify { expect { warn('foo') }.to output("foo\n").to_stderr }
specify { expect { warn('foo') }.to output(/foo/).to_stderr }
specify { expect { }.to_not output.to_stderr }
specify { expect { warn('foo') }.to_not output('bar').to_stderr }
specify { expect { warn('foo') }.to_not output(/bar/).to_stderr }

# deliberate failures
specify { expect { }.to output.to_stderr }
specify { expect { }.to output('foo').to_stderr }
specify { expect { warn('foo') }.to_not output.to_stderr }
specify { expect { warn('foo') }.to output('bar').to_stderr }
specify { expect { warn('foo') }.to output(/bar/).to_stderr }
end

When I run rspec output_to_stderr.rb

Then the output should contain all of these:

| 11 examples, 5 failures | | expected block to output to stderr, but did not | | expected block to not output to stderr, but output "foo | | expected block to output "bar" to stderr, but output "foo " | | expected block to output "foo" to stderr, but output nothing | | expected block to output /bar/ to stderr, but output "foo " |

Using the output_to_stdout_from_any_process matcher

Given a file named "output_to_stdout_from_any_process_spec.rb" with:

RSpec.describe "output.to_stdout_from_any_process matcher" do
specify { expect { system('printf foo') }.to output.to_stdout_from_any_process }
specify { expect { system('printf foo') }.to output("foo").to_stdout_from_any_process }
specify { expect { system('printf foo') }.to output(/foo/).to_stdout_from_any_process }
specify { expect { }.to_not output.to_stdout_from_any_process }
specify { expect { system('printf foo') }.to_not output("bar").to_stdout_from_any_process }
specify { expect { system('printf foo') }.to_not output(/bar/).to_stdout_from_any_process }

# deliberate failures
specify { expect { }.to output.to_stdout_from_any_process }
specify { expect { }.to output('foo').to_stdout_from_any_process }
specify { expect { system('printf foo') }.to_not output.to_stdout_from_any_process }
specify { expect { system('printf foo') }.to output('bar').to_stdout_from_any_process }
specify { expect { system('printf foo') }.to output(/bar/).to_stdout_from_any_process }
end

When I run rspec output_to_stdout_from_any_process_spec.rb

Then the output should contain all of these:

| 11 examples, 5 failures | | expected block to output to stdout, but did not | | expected block to not output to stdout, but output "foo" | | expected block to output "bar" to stdout, but output "foo" | | expected block to output "foo" to stdout, but output nothing | | expected block to output /bar/ to stdout, but output "foo" |

Using the output_to_stderr_from_any_process matcher

Given a file named "output_to_stderr_from_any_process_spec.rb" with:

RSpec.describe "output.to_stderr_from_any_process matcher" do
specify { expect { system('printf foo 1>&2') }.to output.to_stderr_from_any_process }
specify { expect { system('printf foo 1>&2') }.to output("foo").to_stderr_from_any_process }
specify { expect { system('printf foo 1>&2') }.to output(/foo/).to_stderr_from_any_process }
specify { expect { }.to_not output.to_stderr_from_any_process }
specify { expect { system('printf foo 1>&2') }.to_not output("bar").to_stderr_from_any_process }
specify { expect { system('printf foo 1>&2') }.to_not output(/bar/).to_stderr_from_any_process }

# deliberate failures
specify { expect { }.to output.to_stderr_from_any_process }
specify { expect { }.to output('foo').to_stderr_from_any_process }
specify { expect { system('printf foo 1>&2') }.to_not output.to_stderr_from_any_process }
specify { expect { system('printf foo 1>&2') }.to output('bar').to_stderr_from_any_process }
specify { expect { system('printf foo 1>&2') }.to output(/bar/).to_stderr_from_any_process }
end

When I run rspec output_to_stderr_from_any_process_spec.rb

Then the output should contain all of these:

| 11 examples, 5 failures | | expected block to output to stderr, but did not | | expected block to not output to stderr, but output "foo" | | expected block to output "bar" to stderr, but output "foo" | | expected block to output "foo" to stderr, but output nothing | | expected block to output /bar/ to stderr, but output "foo" |