Trace to MsTest v2 test log using TraceSource

224 views Asked by At

I have an old application that was coded with tracing done by calling directly new TraceSource("SourceName").TraceInformation(...). Eventually, I want to review this code and define the source as a static private element but for now I have to deal with it as it is.

When using MsTest v2, the test framework automagically add a listener to System.Diagnostics.Trace.Listeners of type Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TraceListenerWrapper that will copy every trace written to Diagnostics.Trace into the test log accessible in Test Explorer or in Azure DevOps.

My question is: how could I achieve the same result for my (badly implemented) TraceSource?

I already tried creating a TraceSource based on the same name and add the same listener that is in the Diagnostics trace but obviously, this does not work since it is a new instance each time it is called. I also tried to add it in the app.config but the constructor needs to receive a TextWriter as argument.

1

There are 1 answers

0
bkqc On BEST ANSWER

This solution was originally proposed by @Arseni Mourzenko on thread Why are messages sent to trace source missing from all but the first unit test? but still, it works.

Basically, you need to create a custom listener that writes to the Console.

The reason it works by opposition to the standard ConsoleTraceListener is because the latter stores the Console.Out TextWriter in a field during object construction and that Console.Out is a new object for each test.

Since the listeners are initialized only once when configured in app.config (static), it stores only the writer from the first test. The suggested implementation on the other end uses the Console object directly on each call and doing so, writes to the right location.

using System;
using System.Diagnostics;
using System.IO;
using System.Text;

namespace MyNamespace
{
    public class DirectToConsoleTraceListener : TextWriterTraceListener
    {
        public DirectToConsoleTraceListener() : base(new DirectToConsoleTextWriter())
        {
        }

        public override void Close()
        {
        }
    }

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

        public override void Write(string value)
        {
            //Console.Out.Write(value);
            Console.Write(Console.Out.GetHashCode() + ": " + value);
        }

        public override void WriteLine(string value)
        {
            //Console.Out.WriteLine(value);
            Console.WriteLine(Console.Out.GetHashCode() + ": " + value);
        }
    }
}

Registering in app.config

<configuration>
  <system.diagnostics>
    <sources>
      <source name="MyTraceSource">
        <listeners>
          <add name = "ConsoleTraceListener" type="MyNamespace.DirectToConsoleTraceListener, MyAssembly" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
</configuration>