2011-08-17 40 views
1

我想寫入失敗和錯誤發生在測試中的日誌文件,以便它們不出現在屏幕上,但它看起來好像錯誤和斷言失敗寫入STDOUT而不是STDERR。經過數小時的搜索後,我一直無法找到有關如何重定向此輸出的信息,並且非常感謝您的幫助。編寫Ruby測試::單元錯誤和無法文件

+0

您是否有特殊的日誌記錄,或者您的意思是常規輸出?您可以啓動測試腳本並在OS級別重定向。例如:'mytests.rb> log.txt' – knut

回答

1

爲什麼錯誤不是在標準輸出上? 到目前爲止,我還沒有準備好解決方案來抑制特定錯誤的輸出。

如果你接受不變的輸出,我有一個解決方案來存儲文件中的錯誤和失敗。爲通知創建第二個文件將不成問題...

gem 'test-unit' 
require 'test/unit' 

module Test 
    module Unit 
    class TestSuite 
     alias :old_run :run 
     def run(result, &progress_block) 
     old_run(result, &progress_block) 
     File.open('test.log', 'w'){|f| 
      result.faults.each{|err| 
      case err 
       when Test::Unit::Error, Test::Unit::Failure 
       f << err.long_display 
       f << "\n===========\n" 
       #not in log file 
       when Test::Unit::Pending, Test::Unit::Notification, Test::Unit::Omission 
       end 
      } 
     } 
     end 
    end 
    end 
end 


class MyTest < Test::Unit::TestCase 

    def test_1() 
    assert_equal(3, 1+1) #failure 
    end 
    def test_2() 
    1/0 #force an error 
    end 
    def test_3() 
    notify 'sss' 
    end 
    def test_4() 
    pend "MeineKlasse.new" 
    end 
    def test_5 
    omit 'aaa' if RUBY_VERSION == '1.9.2' 
    end 

    def test_5 
    assert_in_delta(0.1, 0.00001, 1.0/10) 
    end 

end 
+0

謝謝!這是我正在尋找的東西。我認爲必須有一些方法來改變Test :: Unit的失敗和錯誤的處理,但我在文檔中找不到對它的任何引用。 –

0

我希望我能理解你的問題是否正確。

你的意思是這樣的:

gem 'test-unit' 
require 'test/unit' 

class StdOutLogger < IO 
    def initialize(*) 
    super 
    @file = File.open('log.txt', 'w') 
    @stdout = true 
    end 
    #write to stdout and file 
    def write(s) 
    $stdout << s 
    @file << s 
    end 
end 
STDOUT = StdOutLogger.new(1) 

class MyTest < Test::Unit::TestCase  
    def test_1() 
    assert_equal(2, 1+1) 
    assert_equal(2, 4/2) 

    assert_equal(1, 3/2) 
    assert_equal(1.5, 3/2.0) 
    end 
end 

但我會建議在操作系統層面來複制標準輸出

ruby mytest.rb > log.txt 

下面是標準輸出和文件輸出之間跳過版本。輸出開關只是一個臨時解決方案 - 也許它可以做得更好。

class StdOutLogger < IO 
    def initialize(*) 
    super 
    @file = File.open('log.txt', 'w') 
    @stdout = true 
    end 
    def write(s) 
    case s 
     when /\AError:/ 
     @stdout = false #change to file 
     when /\A(Pending):/ 
     @stdout = true #change to file 
    end 

    if @stdout 
    $stdout << s 
    else 
    @file << s 
    end 
    end 
end 
STDOUT = StdOutLogger.new(1) 
+0

這是一個解決方案(也適用於@ user899435),問題是它沒有在屏幕上顯示任何內容。我想限制日誌文件只有失敗和錯誤,但保留其他所有內容。我也嘗試在一批斷言之前將STDOUT重定向到一個文件,並在斷言之後將STDOUT切換回舊的STDOUT,但如果有任何錯誤或失敗,則測試退出並且STDOUT不會再變回。 –

+0

我修改了我的答案,允許同時輸出到標準輸出和文件。在我的答案結尾是一個版本,我在標準輸出和文件之間切換。它在一個例子中起作用,但我相信,它必須被修改。我更喜歡一種解決方案,在其中寫入(或複製)標準輸出到文件並準備後期處理。 - 我正在另一個想法 - 更多的細節將隨之而來。 – knut

+0

我發佈了我的其他解決方案:http://stackoverflow.com/questions/7098963/write-ruby-testunit-errors-fails-to-file/7099264#7099264 - 似乎是正確的solutuion;) – knut

1

您是否嘗試將輸出重定向到StringIO,稍後將其寫入日誌文件?

original_stdout = $stdout 
original_stderr = $stderr 
fake_stdout = StringIO.new 
fake_stderr = StringIO.new 

$stdout = fake_stdout 
$stderr = fake_stderr 

你跑再經過測試:

$stdout = original_stdout 
$stderr = original_stderr 

@stdout = fake_stdout.string 
@stderr = fake_stderr.string 

我真的不知道這會的工作,雖然...

+0

感謝提到這個!我遇到了一些'test/unit'測試用例,這些測試用例在我的背後做了這樣的事情,再加上它使用'fakefs' gem,所以寫入日誌文件已經出來了(當我嘗試'debugger' gem時,它大概是因爲stderr&stdout被僞造了)。在我意識到自己可以簡單地做到之前,把我的頭髮拉出來:'STDOUT.puts'hello world''。 – TrinitronX