Headlilne: Microsoft has a new .RunSettings file to replace the previous .TestSettings file so that you can use it with other systems (like NUnit), more easily support Team Build, and improve performance (among other motivations). But does it work yet? I cannot get the GeneratedCode attribute to prevent code coverage analysis of the code.
There are several good posts on the new use of the .runsettings files in Visual Studio 2012. For example:
- http://blogs.msdn.com/b/sudhakan/archive/2012/05/11/customizing-code-coverage-in-visual-studio-11.aspx
- http://msdn.microsoft.com/en-us/library/jj159530.aspx
The User Story
But here is my user story:
As a developer I would like to exclude certain code when I run Analyze Code Coverage from the Test menu of Visual Studio 2012 so that I know what code is not properly tested.
I would like for all my logic and data access to be covered, however there are certain exceptions:
- I don’t care about code coverage of my unit test projects!
- I don’t want to test all the code generated by a Resources.resx file.
- I don’t want to test all the generated code from the Entity Framework.
The Experiments
To see how all this works I created a small solution that looks like this:
And here are the classes shown above:
This class is decorated with the CompilerGenerated attribute.
- [CompilerGenerated]
- public class MyCompilerGeneratedClass
- {
This class has no attributes on the method or the class.
- public class MyCoveredClass
- {
- public void Exercise()
- {
- var name = typeof(MyCoveredClass).Name + ".Exercise()";
- throw new NotImplementedException(String.Format(Properties.Resources.NotImplemented, name));
- }
- }
This has the DebuggerHidden attribute on the method (it cannot be applied to the class).
- public class MyDebuggerHiddenClass
- {
- [DebuggerHidden]
- public void Exercise()
This has the DebuggerNonUserCode attribute on the class.
- [DebuggerNonUserCode]
- public class MyDebuggerNonUserCodeClass
- {
- public void Exercise()
And finally, this one has the GeneratedCode attribute on the class.
- [GeneratedCode("Entity Framework", "5.0")]
- public class MyGeneratedCodeClass
- {
- public void Exercise()
Here are the code coverage results without the use of the CodeCoverage.runsettings file:
So you will notice some interesting things:
- Code Coverage took it upon itself to exclude DebuggerHidden and DebuggerNonUserCode attributed code.
- Today (unlike yesterday on a different project) it did not cover the Resources class. (CodeCoverageLibrary.Properties.Resources.Designer.cs)
So now I’m going to turn on the use of the CodeCoverage.runsettings file:
For unit tests, I add this into my CodeCoverage.runsettings file:
I name my projects <ProjectBeingTested>.Tests, so you might need to change this to match your convention.
Then I added the lines for all the different attributes from various websites:
With these in place, let’s run Code Coverage again. Here are the new results:
So we got rid of the noise from the unit test project, however, the Code Coverage does not seem to have honored my request to exclude the CompilerGenerated or the GeneratedCode attributes. Here are other options I tried with the attribute list shown above:
Now I really didn’t expect for any of those to have an impact because they should all look pretty much the same in the intermediate language (IL). But I’m not that knowledgeable, so I tried them all.
So we are on my user story except that GeneratedCode from the Entity Framework cannot be excluded using that attribute.
The Workaround
Headline: Use the ExcludeFromCodeCoverage attribute.
This is an attribute I wish developers didn’t even know about. I’ve searched that out in the past to prevent its usage. But now I have a choice… Call that code DebuggerHidden or DebuggerNonUserCode – which will bite me later when I’m debugging, or use the ExcludeFromCodeCoverage.
Has anyone else been able to make the GeneratedCode attribute work in preventing code from being analyzed in code coverage in Visual Studio 2012?
Leave a Reply