2011-08-21 165 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); 
     } 
    }