From: Tanaka Akira Date: 2008-10-18T10:50:04+09:00 Subject: [ruby-core:19373] capture_io in minitest capture_io changes $stdout.fileno. It changes puts behavior in child process of IO.popen("-"). In the following test, test_popen fails if test_cap runs first. % cat zc.rb require 'minitest/unit' class TestCap < MiniTest::Unit::TestCase def test_cap out, err = capture_io { puts "foo" } assert_equal("foo\n", out) assert_equal(1, $stdout.fileno) end def test_popen res = IO.popen("-") {|io| if io # parent io.read else # child puts "bar" end } assert_equal("bar\n", res) end end MiniTest::Unit.autorun % ./ruby zc.rb -v Loaded suite zc Started TestCap#test_cap: 0.00 s: F TestCap#test_popen: bar 0.00 s: F Finished in 0.008575 seconds. 1) Failure: test_cap(TestCap) [zc.rb:7]: Expected 1, not 3. 2) Failure: test_popen(TestCap) [zc.rb:20]: Expected "bar\n", not "". 2 tests, 3 assertions, 2 failures, 0 errors, 0 skips The problem is caused by capture_io restores $stdout as dupped $stdout. % svn diff --diff-cmd diff -x -u lib/minitest/unit.rb Index: lib/minitest/unit.rb =================================================================== --- lib/minitest/unit.rb (revision 19827) +++ lib/minitest/unit.rb (working copy) @@ -191,7 +191,7 @@ def capture_io require 'stringio' - orig_stdout, orig_stderr = $stdout.dup, $stderr.dup + orig_stdout, orig_stderr = $stdout, $stderr captured_stdout, captured_stderr = StringIO.new, StringIO.new $stdout, $stderr = captured_stdout, captured_stderr -- Tanaka Akira