Koen about .Net

June 11, 2009

Custom enterprise library logging extender for easy overview of logging in unit tests

Filed under: Development — Tags: , , , — koenwillemse @ 14:59

We have been working on a full new .Net architecture at the recent customer I’m working for. We use a lot of tooling / guidance provided by the Patterns and Practices group of Microsoft. One of the components we are using is the Logging Application Block (part of the Enterprise Library 4.1).

We use a facade which we created to write logentries, which are stored in a file, etc. etc. etc… We also have this functionality in our unit tests which creates one huge log file every time we run all the tests. Very frustrating if you want to find a query that was executed or something like that. We added some markers before and after every unittest, but still, not so great.

Today I implemented a very simple solution for this. I created a custom listener which I configured to be used in the unittest project. The code looks like this:

using System;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;

namespace DemoCode
{
    [ConfigurationElementType(typeof(CustomTraceListenerData))]
    public class ConsoleTraceListener : CustomTraceListener
    {
        /// 
        /// Writes trace information, a data object and event information to the listener specific output.
        /// 
        /// A  object that contains the current process ID, thread ID, and stack trace information.
        /// A name used to identify the output, typically the name of the application that generated the trace event.
        /// One of the  values specifying the type of event that has caused the trace.
        /// A numeric identifier for the event.
        /// The trace data to emit.
        /// 
        /// 	
        /// 	
        /// 
        public override void TraceData(System.Diagnostics.TraceEventCache eventCache, string source, System.Diagnostics.TraceEventType eventType, 
                                       int id, object data)
        {
            var logEntry = data as LogEntry;
            if ((logEntry != null) && (Formatter != null))
            {
                WriteLine(Formatter.Format(logEntry));
            }
            else
            {
                WriteLine(data.ToString());
            }
        }

        /// 
        /// When overridden in a derived class, writes the specified message to the listener you create in the derived class.
        /// 
        /// A message to write. 
        ///                 2
        public override void Write(string message)
        {
            throw new NotImplementedException();
        }

        /// 
        /// When overridden in a derived class, writes a message to the listener you create in the derived class, followed by a line terminator.
        /// 
        /// A message to write. 
        ///                 2
        public override void WriteLine(string message)
        {
            Console.WriteLine(message);
        }
    }
}

Writing to the Console has as an effect that it is displayed in the Test Result View.
Next configure it in the app.config of the testproject and voila, the result when running a test:

The result

The result


Simple right? Why didn’t we think of that earlier…
Just one small thing; we use specific widths for the columns in the logging, which looks good in the plain text log file, but not nicely aligned in the result view for the test. Whatever, the information is there, if it must be nicely aligned, copy/paste it a text editor ;-).

See ya,
Koen

Blog at WordPress.com.

%d bloggers like this: