A TraceListener For Tests
In my code, I make extensive use of debug assertions (see System.Diagnostics.Debug.Assert). These assertions are very helpful while debugging because you don’t need to step into every line of code to see if all pre-conditions are met. As soon as a pre-condition fails, an assertion failed window will pop up and will allow us to either abort, ignore or go to the assertion instruction (retry).
Imagine you have this code:
private void IKnowForSureThatANullStringWillNeverBePassed(string text) { System.Diagnostics.Debug.Assert(string != null, "text is null.");<SPAN style="COLOR: green">// ...
}
Because this method is private, I have full control of what is passed to the text parameter, therefore I’m asserting that it will never be null. Because it might not be obvious that text will never be null, the assertion also acts as documentation.
I usually run my unit tests and integration test on debug compilations and these assertions would be helpful by making the test fail on an assertion fail instead of running through the method and failing with an NullReferenceException. That’s why I (and more people out there) wrote this simple TraceListener:
public class TraceListener : global::System.Diagnostics.TraceListener { public static readonly TraceListener Default = new TraceListener();<SPAN style="COLOR: blue">protected </SPAN>TraceListener() { <SPAN style="COLOR: blue">this</SPAN>.Name = <SPAN style="COLOR: #a31515">"Testing Trace Listener"</SPAN>; } <SPAN style="COLOR: blue">protected </SPAN>TraceListener(<SPAN style="COLOR: blue">string </SPAN>name) : <SPAN style="COLOR: blue">base</SPAN>(name) { } <SPAN style="COLOR: blue">public override void </SPAN>Write(<SPAN style="COLOR: blue">string </SPAN>message) { } <SPAN style="COLOR: blue">public override void </SPAN>WriteLine(<SPAN style="COLOR: blue">string </SPAN>message) { } <SPAN style="COLOR: blue">public override void </SPAN>Fail(<SPAN style="COLOR: blue">string </SPAN>message, <SPAN style="COLOR: blue">string </SPAN>detailMessage) { <SPAN style="COLOR: blue">var </SPAN>builder = <SPAN style="COLOR: blue">new global</SPAN>::System.Text.<SPAN style="COLOR: #2b91af">StringBuilder</SPAN>(); builder.Append(message); <SPAN style="COLOR: blue">if </SPAN>(detailMessage != <SPAN style="COLOR: blue">null</SPAN>) { builder.Append(<SPAN style="COLOR: #a31515">" "</SPAN>); builder.Append(detailMessage); } <SPAN style="COLOR: blue">throw new global</SPAN>::Microsoft.VisualStudio.TestTools.UnitTesting.<SPAN style="COLOR: #2b91af">AssertFailedException</SPAN>(builder.ToString()); }
}
This trace listener won’t write anything to anywhere. It will just throw an AssertFailedException if the Fail method is called, which is what happens when an assertion fails.
Because an assertion window is not desired when running the tests (specially if they are automated tests ran as part of a build process) it’s better to disable the assert UI on the configuration file of the test project.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <assert assertuienabled="false"/> <trace> <listeners> <add name="TestTraceListener" type="PauloMorgado.TestTools.VisualStudio.UnitTesting.Diagnostics.TraceListener, PauloMorgado.TestTools.VisualStudio" /> </listeners> </trace> </system.diagnostics> </configuration>You can find this and other tools on the PauloMorgado.TestTools on CodePlex.