NDepend and Coverage

Published: Sat 09 February 2019

In Blog.


This is the second article in a series regarding NDepend, a code quality and static analysis tool authored by Patrick Smacchia.

The first article in the series can be found here.

Since writing the first article on NDepend there's been an update. A couple of days ago I was notified of the update by means of the built-in Windows notification facility. Also, as I open Visual Studio and click on the NDepend menu item, the dropdown reveals that the update is available for download and install.

New NDepend version available snapshot

The process for upgrading to the new version goes flawlessly, and I'm ready to continue from where I left off at the end of the last blog article. So as mentioned previously, I elected to focus on the technical debt "block" in the NDepend analysis report, and in particular the fact that I noticed that it had reported a warning about not having any coverage data to draw from.

As I mentioned, NDepend supports a number of options when it comes to coverage tool. A free option is, of course, the coverage facility provided by the built-in Visual Studio test runner. xUnit, which is the framework that I'm using in the sample project to write tests, is supported by the VS test runner, but as it turns out, I do, in fact, have a valid license for JetBrains DotCover, and I generally prefer to lean on JetBrains tools when I can, so that's what I've used to generate the coverage information. Generating coverage information is actually quite simple if you have Resharper installed (which I do):

Menu item selecting Resharper cover all tests (and run tests)

This runs tests, and ensures that the DotCover engine is applied to the run in order to get coverage results. The results are none-too-surprising given that this is a TDD kata.

Image showing coverage results

Lobbing the coverage results over to NDepend to use is fairly straightforward as well; Resharper actually has an "to NDepend format" export option!

Image showing coverage results

Once that's done, it's very easy to get the NDepend project to point at the coverage file. Another analysis run indicates that the coverage file has been successfully picked up and parsed.

Image showing a log result that the coverage file was correctly parsed by NDepend

Comparing the technical debt indicator in the final report to that before the coverage file was available yields two additional metrics, namely: Annual Interest and Breaking Point.

Image showing that there are now to new metrics in the corresponding report dashboard block.

So now I'm curious: on this small piece of code (about 25 lines), I have 100% coverage, but I have a 4.82% percentage debt. Digging a little deeper (once again, super straightforward from the web report), there's an explanation of how this value is dervied:

Image showing more detail on the technical debt value, obtained by clicking through the report

My appreciation for how detailed and well thought-out this product is continues to increase as I delve deeper down this technical debt rabbit hole. So, the way in-which the technical debt figure is derived is quite clear, at least in respect of what it is dependent on, that is:

  1. The estimated effort to develop the original code base;
  2. (Obviously), the estimated total time to fix all issues.

The first item in this list then further depends on the number of lines of code and an NDepend project configuration parameter, namely: "Estimated number of man-days to develop 1000 logical lines of code". We'll overlook the use of the gender-specific adjectival noun for the sake of our sanity (how many man-hours have been wasted debating the use of the term "person-hours" instead?). There's also a link in the report to a more in-depth explanation of how debt is derived.

I'm going to delay the discussion around what is said in the in-depth documentation around technical debt and leave with this question: "Why do I have any technical debt at all"?

There's a clue in the issues that have been identified further down in the report:

An image showing the minor issues that have been raised by NDepend

At first glance some of these make sense since I can see that the test class has been picked up as something that isn't instantiated. It's not instantiated explicitly, of course, but is instantiated by the test runner, implicitly. In the next article I'll delve a little deeper into Patrick's thinking around technical debt, and the problem of these sorts of "false positives" on the debt front.

Comments !