In the last article that I wrote on NDepend, I mentioned that the tool had picked up that there was some technical debt to be paid down, and I wasn't clear on the source. I’m going to pick up here to talk about how technical debt is arrived-at by NDepend.
To re-cap: presently I'm limiting my exploration of NDepend to a trivial case: an instance of the string calculator kata. This way I can take small bites out of this elephant … one by one.
As I mentioned in the previous article, I was surprised to find that after having coverage analysed, and reporting 100% coverage, NDepend still insisted that I had a “debt level” of 4.82%. Digging deeper, I found that there were some warnings reported; broken down, they essentially comprise:
- Various warnings about stuff that isn't static that (at least at first glance) can be made static;
- A gripe about multiple types in the same file. None-too-surprising since the way in-which I do this kata is to keep the test class and the tested class in the same file.
Neither of the above problems are, in my opinion, show-stoppers (and I effectively said as much by referring to them as false positives in the previous article—this is arguably going a little far, however). Never-the-less, I appreciate the thoroughness that is being applied. What I am wondering about, though, is how this translates to a 4.82% technical debt value.
But first … I want to make sure that I have an up-to-date report, as I'm aware of the fact that there have been not one by two updates to NDepend since I started blogging about it towards the end of December.
Step 1: clean out everything NDepend-related, and do a complete purge of local settings whilst I'm at it:
$ cd '/c/Users/ESmith/Documents/Visual Studio 2017/Projects/StringCalculator04022018' $ rm *.ndproj $ rm -rf bin && rm -rf obj $ rm -rf NDependOut $ rm -rf packages $ rm -rf .vs
Starting Visual Studio again, and loading the project, I’m not surprised when I’m told that there’s a reference to an NDepend project that doesn’t exist (since I’ve deleted it):
Clicking through this, I rebuild the solution, re-run the tests with coverage, export the coverage file (in NDepend format), and make sure that there’s a new NDepend project created referencing the coverage file. I'm expecting a debt value of 4.82%, naturally … however:
Now, I know that I wasn't supposed to create a clean slate before doing this—after all, what is evident is that NDepend is supposed to be used (and arguably is its most effective int this capacity), tracking code metrics over time. The issue in this case is that I couldn’t understand why I wasn't getting the same figure as before; after all: the source code hadn’t changed. I do understand now that this was as a result of newly introduced rules in a more recent version of NDepend, and sure enough, looking at the underlying reasons for the debt, and trying to match them against changes in the software did indeed yield a “hit”:
8.44% of technical debt, then, will be my new baseline.
A key determinant of technical debt is something that has to start at some “industry norm” value in order to arrive at a debt value, namely estimated number of man-days to develop 1000 logical lines of code.
The image above shows the debt project parameters area of the NDepend project properties (reached through the NDepend | Project menu selection). This parameter is important because it ultimately determines what the final debt percentage is. So the questions then are:
- What's the formula?
- What are the other determinants of the outcome?
Once again, NDepend proves to be eminently discoverable in this regard. I was intrigued by the ”SQALE” acronym used in this section, so hovering over the information icon yielded an explanation:
So the formula is straightforward, it's just the man-time to fix the debt item divided by the man-time corresponding to the relevant section of code. It may be difficult to delineate the section of code that corresponds to one particular technical debt item—it's easier to do so over all identified items, since then the “relevant code component” becomes the entire code base.
NDepend tells me that I have 31 logical lines of code (the majority of-which is made up of test code), so then the theoretical man-time required to finish all the code should be 31*(18)/(1000) = 0.558 man-days. NDepend has also told me that I have 35 minutes (well, technically, man-minutes) to sort all the debt out. 35 minutes = (35)/(60*8) = 0.073 man-days.
I'm therefore expecting (perhaps naïvely so) the debt ratio to be (0.073)/(0.558) = 13%. That is not the case, though, and at this stage, I'm not quite sure why not. In any case, this rabbit hole is proving to have gone deeper than I expected it to at the outset so I will leave the conclusion (and tying-up of this unsatisfactory loose end) to a subsequent article. I've never been fond of instances of "to be continued", but sometimes that's what it has to be.