Dec 6, 2007

How to Exclude a Method from Code Coverage

Let's say you have a piece of C# code in Visual Studio 2005 that looks something like this:

[Serializable]
public class DuplicateRecordException : Exception
{
public DuplicateRecordException()
{
}

public DuplicateRecordException(string message)
: base(message)
{
}

public DuplicateRecordException(string message, Exception innerException)
: base(message, innerException)
{
}

protected DuplicateRecordException(SerializationInfo serializationInfo, StreamingContext streamingContext)
: base(serializationInfo, streamingContext)
{
}
}

And in code coverage analysis you see this:

clip1

You think to yourself “That’s silly! The class is just an exception, there’s no real code there and nothing to really test!  How do I exclude this code from the code coverage calculations?”

What you need to do is add an attribute to each method in the class (it won’t work at class level).  You can use either [System.Diagnostics.DebuggerHidden] or [System.Diagnostics.DebuggerNonUserCode].

If you were to apply these attributes to a couple of methods in the DuplicateRecordException class and then re run coverage analysis you would see the following in the coverage results and the code window:

clip2

clip_image004

Notice that the methods aren’t marked in the source view (meaning they’re not part of the coverage analysis) and that our total non-covered blocks for the DuplicateRecordException class are reduced.

Cool!

Caveats!  Warnings!  Danger!


There are a few things to watch out for here.

Firstly, using the Debugger* attributes changes your debugging experience. DebuggerHidden will prevent you from stepping into the method or setting breakpoints in that code and DebuggerNonUserCode will hide the code as debug time and automatically step over it.  Click the links for more information.

Secondly, and more importantly, exceptions are actually testable.  In the screen shots above you can see that we actually have coverage on the AccountNotFound exception. Not having coverage for an exception is probably an indication that your tests don’t exercise failure conditions and hiding the exception from coverage could be hiding a problem with your unit testing strategy.

1 comment:

  1. I decorate the methods I want to exclude with the following:

    #region ExcludeFromCoverage
    #if CodeCoverageBuild
    [System.Diagnostics.DebuggerNonUserCode]
    #endif
    #endregion


    On our Test/UAT instance of CC.Net we set the "CodeCoverageBuild" directive but not on our dev servers.

    HTH.

    Sam.

    ReplyDelete