c# – 除了第一次单元测试之外,为什么发送到跟踪源的消息都丢失了?

我观察到Visual Studio Enterprise 2015 Update 1的奇怪行为.在单元测试中使用通过.NET Framework TraceSource进行日志记录时,只有第一个单元测试包含日志记录输出.

这是重现问题的方法:

空单元测试项目包含UnitTest1类,如下所示:

using System;
using System.Diagnostics;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class UnitTest1
{
    private readonly TraceSource trace = new TraceSource("Demo", SourceLevels.All);

    [TestMethod]
    public void TestMethod1()
    {
        this.trace.TraceEvent(TraceEventType.Information, 0, "Test 1 (trace source)");
        Console.WriteLine("Test 1 (console)");
    }

    [TestMethod]
    public void TestMethod2()
    {
        this.trace.TraceEvent(TraceEventType.Information, 0, "Test 2 (trace source)");
        Console.WriteLine("Test 2 (console)");
    }
}

App.config文件如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="Demo" switchValue="Critical, Error, Warning, ActivityTracing, Information, Verbose">
        <listeners>
          <add name="ConsoleTraceListener" />
          <add name="TextFileListener" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="ConsoleTraceListener" type="System.Diagnostics.ConsoleTraceListener" />
      <add name="TextFileListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="tests.log" />
    </sharedListeners>
  </system.diagnostics>
</configuration>

从Visual Studio运行测试时:

>第一次单元测试的输出是:

Test Name:  TestMethod1
Test Outcome:   Passed
Result StandardOutput:  
Demo Information: 0 : Test 1 (trace source)
Test 1 (console)

显示来自跟踪源和控制台的消息.
>第二单元测试的输出是:

Test Name:  TestMethod2
Test Outcome:   Passed
Result StandardOutput:  Test 2 (console)

虽然Console.WriteLine的输出效果很好,但是没有显示TraceSource.TraceEvent中的输出.

通过执行mstest /testcontainer:UnitTestProject1.dll从控制台运行测试也会重现问题.第一次测试报告的标准输出包含两行;第二个测试的标准输出只有一行.

除了第一次测试之外,为什么没有跟踪记录?

最佳答案 解决方法包括包装默认的TextWriter,它使用底层的Console.Out文本编写器来发送日志:

public class CustomTextWriter : TextWriter
{
    public override Encoding Encoding
    {
        get
        {
            return Console.Out.Encoding;
        }
    }

    public override void Write(string value)
    {
        Console.Out.Write(value);
    }

    public override void WriteLine(string value)
    {
        Console.Out.WriteLine(value);
    }
}

然后,编写器将用于类似于one used in .NET Framework的自定义跟踪侦听器:

public class ConsoleTraceListener : TextWriterTraceListener
{
    public ConsoleTraceListener() : base(new CustomTextWriter())
    {
    }

    public override void Close()
    {
    }
}

这在App.config中声明如下:

<add name="ConsoleTraceListener"
     type="UnitTestProject1.ConsoleTraceListener, UnitTestProject1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />

这产生了预期的输出,尽管仍然不清楚为什么问题首先存在.通过检查Console.Out和底层流,在第一次测试结束后似乎没有处理或关闭的东西(如果它会,为什么the current implementation of Out什么也不做,以及为什么发送到Console.WriteLine的文本出现在日志中? )

点赞