NCOVER – THE MODULES THAT TIME FORGOT

A recent support question surfaced an issue that many of us have overlooked. NCover’s coverage reports show us the coverage of the tested assemblies, right? And certainly our tests load all the assemblies that we’re building, right? And we’ve manually verified that all of our assemblies are listed in our coverage reports, right? If that’s you, GOTO END.

For the rest of us… what about the assemblies that no one tested? Well, they are blissfully hidden from the nightly coverage reports in most of our build processes. The following technique is one simple way to make sure that these forgotten assemblies show up in coverage reports even when no tests are written to passively load these assemblies.

This example demonstrates how to force assemblies to be loaded into an NUnit test process. Most other testing frameworks use almost identical code. First, create a new test setup fixture. It should be sufficient for this fixture to live in any one of your test assemblies or if you prefer it can exist on its own. The key is that it will generate the outliers and be merged in with your other coverage data as the collection progresses or when your merge task is run.

EXAMPLE FIXTURE

  [TestFixtureSetUp]
  public void ForceLoadAssembly() {
  // Force all .dll assemblies under the specified directory to be
  // loaded into the process so NCover will include them in the
  // coverage analysis.
     foreach (var filename in Directory.GetFiles(@"C:\my\executables\", "*.dll")) {
        try {
            Assembly.LoadFrom(filename);
        } catch (Exception e) {
            Console.WriteLine("Unable to load {0}.", filename);
        }
     }
  }

THE OUTPUTS

The effect of adding this setup fixture to your tests will be to search the specified location for assemblies that match the file mask provided. These assemblies are manually loaded by the setup fixture. If the assembly is a native binary, then the code above will simply output the message that the assembly could not be loaded.

When the setup fixture loads a managed assembly, NCover will capture that event and collect coverage on that assembly provided it has not been otherwise excluded from coverage. In this way coverage exclusions still apply. The positive result of this action is that all managed assemblies are now listed in the coverage reports with the default level of 0% coverage if no other action ever hits that assembly.

Maybe it’s time for us to recapture some coverage baselines.

FULL ASSEMBLY CODE

using System;
using System.Text;
using NUnit.Framework;
using System.Reflection;
using System.IO;

  namespace ForceLoad {

    [TestFixture]
    public class ForceLoad {

      [TestFixtureSetUp]
      public void ForceLoadAssembly() {
        // Force all .dll assemblies under the specified directory to be loaded into
        // the process so NCover will include them in the coverage analysis.
        foreach (var filename in Directory.GetFiles(@"C:\executables\", "*.dll")) {
          try {
             Assembly.LoadFrom(filename);
          } catch (Exception e) {
             Console.WriteLine("Unable to load {0}.", filename);
          }
        }
      }

      [Test]
      public void Test1() {
        Assert.IsTrue(true);
      }

      [Test]
      public void Test2() {
        Assert.IsTrue(true); 
      }

    }
  }

Special thanks to the full NCover support team!