Capturing stdout during unit tests

I've written a script for use with Nagios (a monitoring tool) that I'd like to test. The requirements for the script is that it output a single line of text to STDOUT and then exit with a status code (0 - 3). My script is designed to monitor a few different services... each invocation includes a required command line argument specifying the service to monitor in the current invocation. To do that, I created a class for each type of service monitor.

I'm now writing unit tests for my script, and I'd like to check that the output written to STDOUT by each service monitor class is correct. But I'm new to Ruby and I'm not sure how to do that. In other languages, I'd simply redefine STDOUT as a stream that goes to a large in-memory buffer, but I haven't seen anything that suggests that is possible in Ruby. The best I've come up with so far is creating a temporary file and calling $stdout.reopen() with the path to that temporary file. However, I'd much rather do this in memory because then I never have to worry about what file system and permissions the user executing the unit test has.

Thanks,

Mark

Try this:

require 'stringio'

$stdout = StringIO.new

(This will break in IRB w/ Readline)

StringIO has all the IO methods, but acts on a string, not a file. So you should be able to do what you want.

Cheers

Phil

···

On 8/08/2007, at 3:59 PM, Mark Slater wrote:

I've written a script for use with Nagios (a monitoring tool) that I'd like to test. The requirements for the script is that it output a single line of text to STDOUT and then exit with a status code (0 - 3). My script is designed to monitor a few different services... each invocation includes a required command line argument specifying the service to monitor in the current invocation. To do that, I created a class for each type of service monitor.

I'm now writing unit tests for my script, and I'd like to check that the output written to STDOUT by each service monitor class is correct. But I'm new to Ruby and I'm not sure how to do that. In other languages, I'd simply redefine STDOUT as a stream that goes to a large in-memory buffer, but I haven't seen anything that suggests that is possible in Ruby. The best I've come up with so far is creating a temporary file and calling $stdout.reopen() with the path to that temporary file. However, I'd much rather do this in memory because then I never have to worry about what file system and permissions the user executing the unit test has.

Thanks,

One option is to write your test to execute your script on the command
line. I'm pretty sure this is the piece you're missing:

# asign the shell output of the ls command to a variable
ls_output = `ls`

# Do something semi-useful with it.
items = ls_output.split
puts "There are #{items.size} objects in the directory."

-Simon

Mark Slater wrote:

···

I've written a script for use with Nagios (a monitoring tool) that
I'd like to test. The requirements for the script is that it output a
single line of text to STDOUT and then exit with a status code (0 -
3). My script is designed to monitor a few different services... each
invocation includes a required command line argument specifying the
service to monitor in the current invocation. To do that, I created a
class for each type of service monitor.

I'm now writing unit tests for my script, and I'd like to check that
the output written to STDOUT by each service monitor class is
correct. But I'm new to Ruby and I'm not sure how to do that. In
other languages, I'd simply redefine STDOUT as a stream that goes to
a large in-memory buffer, but I haven't seen anything that suggests
that is possible in Ruby. The best I've come up with so far is
creating a temporary file and calling $stdout.reopen() with the path
to that temporary file. However, I'd much rather do this in memory
because then I never have to worry about what file system and
permissions the user executing the unit test has.

Thanks,

Mark

--
Posted via http://www.ruby-forum.com/\.

I've written a script for use with Nagios (a monitoring tool) that
I'd like to test.

<snip>

I'm now writing unit tests for my script, and I'd like to check that
the output written to STDOUT by each service monitor class is
correct. But I'm new to Ruby and I'm not sure how to do that. In
other languages, I'd simply redefine STDOUT as a stream that goes to
a large in-memory buffer,

What language is this in?

but I haven't seen anything that suggests that is possible in Ruby.

At any rate, Ruby does have similar functionality. An example:

require 'stringio'
class Bs
   attr :output_stream,true

   def do_some_output(data)
    output_stream.puts(data)
   end
end

bs=Bs.new
bs.output_stream=$stdout
bs.do_some_output("this is to stdout")

expect="grrrrrrrr"
result=String.new

bs.output_stream=StringIO.new(result,"w+")
bs.do_some_output("Waka waka waka!")
bs.output_stream.close

puts "result= " + result
puts "expect= " + expect

[sshaw@localhost sshaw]# ruby bs.rb
this is to stdout
result= Waka waka waka!
expect= grrrrrrrr

···

On Aug 7, 8:59 pm, Mark Slater <li...@humanesoftware.com> wrote:

Install the ZenTest gem, then:

require 'test/zentest_assertions'

class TestBlah < Test::Unit::TestCase

   def test_my_stuff
     out, err = util_capture do the_thing end
     assert_equal "...", out.string
     assert_equal "...", err.string
   end
end

···

On Aug 7, 2007, at 20:59, Mark Slater wrote:

I've written a script for use with Nagios (a monitoring tool) that I'd like to test. The requirements for the script is that it output a single line of text to STDOUT and then exit with a status code (0 - 3). My script is designed to monitor a few different services... each invocation includes a required command line argument specifying the service to monitor in the current invocation. To do that, I created a class for each type of service monitor.

I'm now writing unit tests for my script, and I'd like to check that the output written to STDOUT by each service monitor class is correct. But I'm new to Ruby and I'm not sure how to do that. In other languages, I'd simply redefine STDOUT as a stream that goes to a large in-memory buffer, but I haven't seen anything that suggests that is possible in Ruby. The best I've come up with so far is creating a temporary file and calling $stdout.reopen() with the path to that temporary file. However, I'd much rather do this in memory because then I never have to worry about what file system and permissions the user executing the unit test has.

--
Poor workers blame their tools. Good workers build better tools. The
best workers get their tools to do the work for them. -- Syndicate Wars

Awesome! Thank you. That's exactly the functionality I was looking for.

Mark

···

On Aug 8, 2007, at 12:08 AM, Eric Hodel wrote:

On Aug 7, 2007, at 20:59, Mark Slater wrote:

I've written a script for use with Nagios (a monitoring tool) that I'd like to test. The requirements for the script is that it output a single line of text to STDOUT and then exit with a status code (0 - 3). My script is designed to monitor a few different services... each invocation includes a required command line argument specifying the service to monitor in the current invocation. To do that, I created a class for each type of service monitor.

I'm now writing unit tests for my script, and I'd like to check that the output written to STDOUT by each service monitor class is correct. But I'm new to Ruby and I'm not sure how to do that. In other languages, I'd simply redefine STDOUT as a stream that goes to a large in-memory buffer, but I haven't seen anything that suggests that is possible in Ruby. The best I've come up with so far is creating a temporary file and calling $stdout.reopen() with the path to that temporary file. However, I'd much rather do this in memory because then I never have to worry about what file system and permissions the user executing the unit test has.

Install the ZenTest gem, then:

require 'test/zentest_assertions'

class TestBlah < Test::Unit::TestCase

  def test_my_stuff
    out, err = util_capture do the_thing end
    assert_equal "...", out.string
    assert_equal "...", err.string
  end
end

--
Poor workers blame their tools. Good workers build better tools. The
best workers get their tools to do the work for them. -- Syndicate Wars

Install the ZenTest gem, then:

require 'test/zentest_assertions'

class TestBlah < Test::Unit::TestCase

   def test_my_stuff
     out, err = util_capture do the_thing end
     assert_equal "...", out.string
     assert_equal "...", err.string
   end
end

if you're not using test/unit:

require 'test/zentest_assertions'
include Test::Unit::Assertions

···

--
Posted via http://www.ruby-forum.com/\.