Customizing the behavior of System.Diagnostics.Debug.Assert [Matt Ellis]
When Inbar posted his
refresher on the System.Diagnostics.Debug class, Ron Cain asked
an interesting question about Assert in the context of a test harness. Because
of this I thought it might be nice to expound on some of the details on exactly
how Debug.Assert ends up popping up UI when a failure occurs and what you can
do to change this behavior.
We’ll start by discussing what happens when a simple call
like Debug.Assert(false) is made. All Debug.Assert does is check the condition
and if its value is false (as it is in this case) calls Debug.Fail with
String.Empty as the message. When Debug.Fail is called, we iterate over
theTrace.Listeners collection and call the Fail method on each listener and then
return. The subtle point here is that Debug.Assert doesn’t pop up the
assertion failed dialog, but instead some listener in the Trace.Listeners
collection does. The listener that does this is called the DefaultTraceListener.
As its name suggests, the DefaultTraceListener is added by
default to the Trace.Listeners collection when your application runs. If you
want, you can remove this listener either by calling
Trace.Listeners.Remove(“Default”) at some point in your app or by using an
application configuration file that removes the listener. An example
configuration file would look like:
<configuration>
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
If you do either of these two things and then call
Debug.Assert(false) your app will continue to run and you’ll have no indication
that your assertion failed. If you just want to disable the UI but continue to
have debugging messages written to the OutputDebugString (or to a log file if
you have specified the DefaultTraceListener.LogFileName property) you can set AssertUiEnabled
property on the DefaultTraceListener object to false.
Now, to answer Ron’s question on how you can get
Debug.Assert() to play nice within your testing environment. The answer
depends somewhat on what your hosting environment is like. If your tests
simply run applications and check their return codes you could write a custom
trace listener that calls System.Environment.Exit with a special error code
whenever Fail is called. Perhaps instead you may choose to write a stack trace
when an assert is fired to a predefined output file that your testing harness
checks when it returns, if the file is empty after your test case runs then you
know there were no asserts.
Hopefully this has helped to remove some of the mystery
behind the Assert method on the System.Diagnostics.Debug class. If you have
further questions about anything in the Diagnostics name space feel free to
drop a comment and I’ll try to respond.
Cheers!