Smart Technical Debt Estimation with NDepend

It’s been less than a year since I last wrote a blog about NDepend. And here again, I’m writing about an awesome static analysis tool that everyone likes. I must confess that I had no idea on static analysis and analyzer before having an encounter with NDepend. Only after going through NDepend, have convinced me that this type of tool can really make our developing/managing life plain, simple and easy. However, in the middle of the last year I was totally converted to a guy who now drinks, eats and sleeps in the realm of .net core. And back then there wasn’t any support available from any static analysis tool for .net core projects. But now on the recent version (2017.1.1), NDepend is supporting .net core projects and believe me it's super-fast when it comes to the fact that a lot of code rules must be verified on a huge codebase on every compilation. It’s just a matter of seconds. I also like the new cool looking dashboard where you can have an eagle-eye view of your project’s health.

I talked about some core features of NDepend in this blog. Check that out if you want to have a good to go idea on NDepend. In this post I’m going to talk about a new feature of NDepend called smart technical debt estimation.

The term technical-debt is a metaphor developed by Ward Cunningham in 1992. In simple words, it states that applying a hackable solution to an issue in the codebase may struck us with a technical debt in the future. If a quick and dirty fix on the solution causes us to pay interests in form of extra hours of human efforts later, then we should reduce the cumulative interests by consider a refactoring on the solution. Just like credit card payments, if you buy something with it, it is considered as a loan and the amount of interest grows with time. The faster you pay off the debt the less interest amount you have to pay for it. Same idea is applied here, steps you take early to fix a code smell will relieve you from a bigger future debt.

Martin Fowler have taken an extra step to make the metaphor more easy to understand. In this blog he described technical debt estimation in more details.

NDepend can estimate technical-debt in a smarter way through its very own ruleset defined using C# LINQ queries. These rules are very much modifiable and you should modify them according to your needs.

Let’s go for some little more detail. So, I had a project which provides some custom request/response formatters for .net core. Three days ago, I installed NDepend and ran a analysis on my codebase but didn’t really understood the whole idea of the term Baseline. Today when I added a new formatter, I intentionally left the formatter class unimplemented and ran the analyzer again. Both results are shown below (before and after sequence)

Three days before

Today (After adding a new formatter class and leaving it unimplemented.)

If you notice on the top rectangle box there is an option for selecting baseline. As you can see NDepend is intelligent enough to take the report that was generated three days ago as a baseline and when I reanalyzed, it is comparing that report to my current one; showing me the extra debt added to my codebase.

I also have two major issues in the right bottom rectangle. I should fix them before they get out of my hands.

There are also some quality gates which we should take into consideration when trying to push our changes to source control or in production. Our code must pass through quality gates by hook or by crook.

Now after I fixed those major issues and reanalyzed. The report is like below,

As you can see, three new issues just popped up. That’s because I’ve changed the namespace of a given type in my codebase to satisfy a previous rule set. I’ve gone through the LINQ queries of these rule set and found that this line of code is generating them,

(!m.WasRemoved() && m.ReturnType != null && m.NewerVersion().ReturnType != null
                     && m.ReturnType.FullName != m.NewerVersion().ReturnType.FullName)

Now these rule sets are doing the jobs they are supposed to do. It is really causing a API breaking change when I’m modifying the namespace of a type which is actually used in my other methods. In this type of case, you exactly know that the changes you made is actually for the betterment of your codebase so you are left with two options. Either you modify and remove the line of code from the rule set (not preferred) or just set the baseline to none and run the analysis again.

I choose the second option and after running the analysis again my report now looks like this,

Notice that at the beginning my technical debt of the codebase was 5.82%, which is now decreased by 13%. So, the API breaking change wasn’t so much of a breaking change actually since it was only comparing itself to its last baseline and showing warnings relative to that baseline.

Now, I should say that this smart technical-debt estimation technique of NDepend is actually pretty smart. Frankly speaking; after going through this new feature and all the other features; I’m convinced and sure that I’ll use NDepend to analyze my codebase in a completely new way. I don't know about you but to me, NDepend is a way of establishing a new court of justice for your codebase, period!