Best Practices for Pre-Coverage Filters

pre_coverage_filtersNCover is designed to easily collect code coverage on the build server, across multiple machines and across entire development or QA teams. These deployment options, combined with NCover’s ability to collect coverage regardless of testing method, including manual and automated tests, provides the industry’s most comprehensive solution for complete .NET code coverage.

Although NCover has been optimized to handle large volumes of coverage data, many users choose to focus coverage on specific sections of code during development and testing cycles. There are many reasons for this, including the desire to reduce system and resource utilization, the need to reduce cycle time by focusing on code known to have changed, or the need to align the coverage process with organizational objectives.

One of the best ways to focus the collection of coverage is through the use of pre-coverage filters, which is a recommended best practice for all NCover users. 

Why Use Pre-Coverage Filters?

Pre-coverage filters prevent code profiling and data collection for items specified in the pre-coverage filter.

Using pre-coverage filters to narrow coverage data has two primary benefits:
1.  Reduces the data store size, the overall profiling load and improves collection speed and performance.
2.  Simplifies report creation, particularly reports including method and class details.

Best Practices For Pre-Coverage Filters

NCover’s pre-coverage filters allow for a wide range of usage scenarios.  However, there are several best practices to ensure that your pre-coverage filters both achieve your desired result and are used in the most efficient way possible.

Focus On The Module

When using the pre-coverage filters Include and Exclude, we recommend focusing those rules at the Module level. If you want to exclude more specific parts of the underlying classes, we recommend using post-coverage filters. An exception to this rule is if you want to exclude generic patterns like .ctor or .cctor.

We do not recommend the use of include filters for namespaces, classes, and methods in the pre-coverage filter for a project. There are three primary drawbacks:

  • Filters on namespace, class, and method apply to all modules and so do not eliminate modules, they only filter the contents during collection. Ultimately, this does not save time or space.
  • Collateral classes with coverage help to reinforce successful coverage collection on new classes. If a new class shows as uncovered, but an old class shows as covered, then the user has more reason to believe that further testing is needed, rather than suspect the coverage was somehow dropped in error.
  • Saving a post-coverage filter by build-id or version allows you to continue to revisit the coverage of previous test runs without losing the ability to trend the coverage of a module across time.

In general, you want to develop pre-coverage filters that create the shortest possible list of filters. In addition to improving processing time, it removes potential confusion from the use of overly complicated rules. You should also consider using Regex rules, where appropriate.

Include or Exclude

Exclude filters are fairly straightforward. Collection will be captured for everything except what has been specifically excluded. This approach ensures that any new assemblies will be captured and included in the coverage analysis.

Include filters, on the other hand, require that each module be specifically named to be included in the coverage. This approach offers benefits in large systems that load a large number of DLLs. However, it is important to remember that any completely new assemblies will need to be added manually to the filter list.

Follow the Flow

When both Include and Exclude pre-coverage filters are used, Includes are applied first and then Excludes are applied, or subtracted from, what was originally included. This provides the option to target very specific areas of code, but it is important to remember that this logic will be applied in this order regardless of the order in which the pre-coverage filters are created.

Also, when using both Include and Exclude pre-coverage filters, you want to eliminate filters that duplicate effort. For instance, if you Include Module A, you do not need to Exclude Module B. Module B is already excluded by definition when the filter logic is applied.

Test Your Filters

Just as you should always test your code before you deploy it, you should always test your coverage collection before your begin a testing cycle. We recommend running a limited test of your coverage settings and inspecting the data collected by NCover. This is true whether you are running only NCover Code Central on your build server or you are collecting coverage from a variety of machines. It’s very frustrating to run through an entire testing cycle only to discover that your filters excluded key Modules or included large portions of code that you did not want in your analysis.

You can easily get Module summary data by using either the Summarize command or the Report command. Either of these commands can help verify that the correct modules are getting loaded and covered.
If you want to investigate coverage on a machine where Collector is installed, your can pause syncing to Code Central. This will allow you to limit your analysis to only that machine.

Troubleshooting

If you need to troubleshoot a pre-coverage filter, set the logging level of the project to Verbose. You can then check the profiling logs for entries that match the following pattern:

ClassLoaded ---- Name[%s] Explicit include(%s) exclude(%s)

This will show you exactly how NCover is applying pre-coverage filters in your coverage.