2011-08-21 101 views
22

我剛開始測試xUnit.net,但它似乎沒有捕獲任何輸出(控制檯,調試,跟蹤),因爲我會預料到的。xUnit.net不捕獲控制檯輸出

這可能嗎?我正在使用xUnit.net 1.8的示例.NET 4.0類庫。

回答

3

一般來說,依靠記錄測試是一條糟糕的道路。合格/不合格應該是測試的結果。而且他們根本不應該進入足夠的事情發展階段,因爲需要追蹤蹤跡。

xunit.gui.exe顯示控制檯和跟蹤輸出,xunit.console.exe沒有。如果它很重要,可以通過製作適當的標準.NET配置條目(Theres'FileWriterTraceListener,如果你將它放入其中,你應該可以掛鉤)來連接重定向到文件的TraceListener。


UPDATE:如his blog post討論的,達米安希基具有可能的替代品的一個很好的例子 - 佈線記錄到的xUnit 2 ITestOutputHelper如示https://github.com/damianh/CapturingLogOutputWithXunit2AndParallelTests/blob/master/src/Lib.Tests/Tests.cs

更新2:在一些情況下,可以添加日誌記錄,並喂到ITestOutputHelper沒有通過如下使用一個簡單的適配器涉及LogContext(我只是有它在F#,不好意思):

// Requirement: Make SUT depend on Serilog NuGet 
// Requirement: Make Tests depend on Serilog.Sinks.Observable 

type TestOutputAdapter(testOutput : Xunit.Abstractions.ITestOutputHelper) = 
    let formatter = Serilog.Formatting.Display.MessageTemplateTextFormatter(
     "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}", null); 
    let write logEvent = 
     use writer = new System.IO.StringWriter() 
     formatter.Format(logEvent, writer); 
     writer |> string |> testOutput.WriteLine 
    member __.Subscribe(source: IObservable<Serilog.Events.LogEvent>) = 
     source.Subscribe write 

let createLogger hookObservers = 
    LoggerConfiguration() 
     .WriteTo.Observers(Action<_> hookObservers) 
     .CreateLogger() 
let createTestOutputLogger (output: ITestOutputHelper) = 
    let adapter = TestOutputAdapter testOutputHelper 
    createLogger (adapter.Subscribe >> ignore) 

type Tests(testOutputHelper) = 
    let log = createTestOutputLogger testOutputHelper 

    [<Fact>] let feedToSut() = 
     // TODO pass log to System Under Test either as a ctor arg or a method arg 

的區別w ^採用這種方法vs使用日誌上下文是記錄到全局[contextualized] Serilog Logger不會被拿起。

+1

謝謝您的答覆。 我正在使用xunit.console.exe。 我知道這不是一個好的解決方案,它不是真正的預期用途。我需要它的原因是在使用TDD創建新類時調試一些字符串操作。 – kfuglsang

+0

我個人只是將xunit.console.exe設置爲調試器中的啓動項目。順便說一句,TeamCity和其他類似的運行環境會在你尋找 –

+0

@downvoter的時候提取測試結果爲什麼? (順便提一下,V2中有計劃的工作來阻止數據被吞噬......) –

2

有一個解決方案,在這裏找到:https://xunit.codeplex.com/discussions/211566

只需添加到您的構造函數或方法,您要調試輸出:

Debug.Listeners.Add(new DefaultTraceListener()); 
+1

對於稍後的調整,這不再是推薦的做法。請參閱http://xunit.github.io/docs/capturing-output.html。 –

+4

哦,那些xunit傢伙,如果它不夠複雜,它不是xunit -.- Ofc在.Net Core上沒有IMessageSink .... MsTestV2來拯救! – MushyPeas

24

的情況變化不大xUnit.net 2。我知道這個問題是關於早期版本的,但是隨着人們在這裏進行升級,我認爲值得指出這一點。

爲了在版本2中看到測試輸出中的某種輸出,您需要在測試類(通過構造函數參數)上對ITestOutputHelper的實例進行依賴,然後在該接口上使用WriteLine方法。例如: -

public class MyTestSpec 
{ 
    private readonly ITestOutputHelper _testOutputHelper; 

    public MyTestSpec(ITestOutputHelper testOutputHelper) 
    { 
    _testOutputHelper = testOutputHelper; 
    } 

    [Fact] 
    public void MyFact() 
    { 
    _testOutputHelper.WriteLine("Hello world"); 
    } 
} 

你可以選擇你的日誌框架鉤到這個接口,或許通過注入ILog實現,轉發所有呼叫ITestOutpuHelper

我承認你不想在默認情況下這樣做,但爲了診斷目的,它可能會非常有用。當您的測試僅在基於雲的構建&測試服務器上失敗時尤其如此!

+1

順便說一下,ITestOutputHelper位於Xunit.Abstractions命名空間中。 – Syndog

+0

[官方示例代碼](https://github.com/xunit/samples.xunit/blob/master/TestOutputExample/Example.cs)。它仍然適用於.NET核心項目。 – zwcloud

+0

如果您已經在此MyTestSpec構造函數中傳遞了自定義對象實例(即MyDatabaseFixture)而不是ITestOutputHelper,該怎麼辦? –

1

這可以幫助,如果你的Console.Write被嵌入在內心深處,你不想重構一些類層次結構:

public MyTestClass(ITestOutputHelper output) 
    { 
     var converter = new Converter(output); 
     Console.SetOut(converter); 
    } 

    private class Converter : TextWriter 
    { 
     ITestOutputHelper _output; 
     public Converter(ITestOutputHelper output) 
     { 
      _output = output; 
     } 
     public override Encoding Encoding 
     { 
      get { return Encoding.Whatever; } 
     } 
     public override void WriteLine(string message) 
     { 
      _output.WriteLine(message); 
     } 
     public override void WriteLine(string format, params object[] args) 
     { 
      _output.WriteLine(format, args); 
     } 
    }