As developers Unit Testing makes our jobs easier, we have consistent tests to validate our work, change management becomes easier, and we can prove the functionality remains the same. In collaboration with various companies, however, I find that often the tooling gets in the way of developers understanding exactly how much of their important code is covered by unit tests. Visual Studio provides unit test coverage tools for reporting, yet often the tool ends up discouraging users due to a lower than expected rate of coverage. In this post, we will investigate a few common areas that can impact your unit test coverage, and how to prevent certain items from changing the reported coverage percentage.
Using one of my projects as an example, I utilized the Visual Studio "Analyze Code Coverage" option for all Unit Tests in my solution. The result was far less than I had expected and I started to drill into the specific areas that it was showing as "not covered." Upon further investigation, I found that my use of Entity Framework migrations resulted in one of the largest areas of no coverage. So how do we fix this?
Why Not Write a Test?
In the case of this example, I don't want to write a unit test to verify that each migration does exactly what it should. You might disagree with that answer, but the key here isn't necessarily the exact situation it is the fact that we don't want this migration to impact my reported code coverage. The same technique here could apply to shared code, other auto-generated code, or other functions that you just don't want changing your coverage numbers.
In my case, I'm very firm that I don't want to have this code tested. And it shouldn't change the percentage of coverage in my solution.
Microsoft provides us an attribute [ExcludeFromCodeCoverage] (Within the System.Diagnostics.CodeAnalysis namespace) that you can add to any class, method, property, field, or constructor. This attribute signals to the code coverage tools that it shouldn't be concerned regarding the coverage of this particular object within the reporting.
In my case, this improved the code coverage percentages within my solution by more than 11% as this was a long established solution with many migrations.
Not a tool to be used lightly, but by using the [ExcludeFromCodeCoverage] attribute you can take better control over your code analysis and better manage your adherence to unit testing standards. I find this particularly useful with Entity Framework Migrations, actual unit test projects, legacy code that for whatever reason doesn't meet unit testing requirements, or service references. Your results may vary, but I hope this helps!