Quantifying code quality with NDepend – An introduction

I have been obsessed by static code analysis in recent years and it’s only recently that the tooling around this has become more widely adopted in software development teams, from my perspective anyway. I’m sure the developers creating these tools have seen the value in them for many years. As usual, ideas take a while to permeate throughout an industry and sadly I’ve only come to realise their true value in the past two years.

This is not a sponsored post and am not being paid by NDepend.

Put simply they point out potential problems and areas of concern within a code base and prevent developers repeating the same mistakes. For me it’s the biggest reason to place a static analysis tool in your build pipeline. Besides, who wants to scan thousands of lines of code looking for defects? This is a job for an automated process.

If you’ve ever struggled as a team to decide on what to refactor or what the pain points in the code base are, then the metrics these tools offer can guide you and perhaps even be solid reason to focus your efforts in a particular area.

Defining quality with metrics

Quality is a subjective topic and it means so many things to different people that it’s difficult to agree on a single set of principles. Using a tool such as NDepend will present you with several metrics, best practices, guidelines and insights that a team of developers can decide which are the most important.

Consistency is also another great reason to use a tool like NDepend. Not only for a single project but for several projects across your organisation. Once your team agrees on a measure of quality, then enforcing this becomes relatively painless. Less time in meeting rooms and more time focused on agreed quality metrics and best practice rules.

An example of a simple metric most developers agree on is lines of code for a single method or class being a reasonable size. Again that number depends and with NDepend these numbers are configurable. If you come from a team of sceptical developers who are new to these concepts then perhaps a simple metric such as lines of code can be used.

Starting small

Although I’ve been using NDepend on a couple of personal projects, I’m writing this blog post as I’m learning about NDepend. There’s a difference between poking around and writing about it. Writing this post is forcing me to be more thorough so I’ll be starting with a small example which will increase in complexity over time which will allow me to analyse trend graphs and show how quality measures change. I will also analyse more complex code bases from some popular open source projects such as NopCommerce and Umbraco which are closer to a real world scenarios where you have a production grade code base being analysed for the first time and how to dissect the results.

To start off you’ll need to download and install NDepend. Once the installation is complete NDepend can be used as a standalone product or as a Visual Studio extension. Throughout this series of posts I’ll be in and out of both to get a feel of both environments. To start off I’ll explore it through Visual Studio where it’s nice and warm.

Once installed, you’ll see a new menu within Visual Studio.

ndepend menu

To start off with I’ll open an empty console application and attach NDepend. Attaching NDepend simply creates an NDepend project file which stores settings.

ndepend_attach

This nice thing about being able to save the project elsewhere is that you don’t need to commit it to source control (although it’s good practice) until you’re comfortable with the tool.

Click the analyze button and NDepend does its thing.

ndepend_proj_analysis

Once complete NDepend will produce a HTML report which will open in your browser and also display a beginner dialog. At this point it’s best to go to the dashboard to get an overview of our project. The HTML report will be extremely useful artifact as a post build step in your continuous integration system.

ndepend-dashboard
NDepend Dashboard
ndepend-widget-1
NDepend Dashboard Widget

There are various widgets which display information, all of which is useful. At a glance you can see a few interesting numbers:

  • Lines of code
  • IL method complexity – An extremely useful metric as the C# compiler often expands our syntactic sugar to many more lines of C# code which in turn translates to several hundred more lines of IL instructions. A good example is yield return or async await state machines.
  • Number code rules in violation – NDepend comes with a whole library of built in best-practice rules which can be customised on the fly. The “rules engine” is at the heart of this product and I’ll briefly take a look at it.
  • Other charts which show various trends over time.

The trend graphs could provide huge value to a tech lead or project manager to get a sense of how agreed upon quality is changing overtime. I literally can’t wait to dive deeper into this tool and where it fits in our workflow.

At this point there virtually no code in my console application. I’m going to add a method to implement the infamous FizzBuzz test and then add other conditions to show method complexity.

The following method has a complexity of 1.

Now I’ve added a FizzBuzz method which has a complexity of 3.

Adding a third if statement testing if a value is both divisible by 3 and 5 increases the complexity to 5.

The complexity has increased and so have the statistics, things are working nicely. The changes however are not instant and the project needs to be rebuilt and re-analysed and this highlights NDepend’s purpose. It’s a reporting tool and not meant for instant feedback. Very much a tool for a technical or project lead and part of the continuous build pipeline, building reports and providing developers with information about the health of their code base.

ndepend_method_complexity

The heart of NDepend

At the heart of NDepend is the CQLinq query engine which gives you the ability to write LINQ expressions against your source code. The entire product is build around these queries and is responsible for all of the metrics and best practice rules. The existing rules can be customised to suit your needs and you can even write your own. For the sample code shown above I wrote a simple query which dumps every method and its complexity value. To get to the editor: NDepend > Windows > Rule Edition will bring up the editor

ndepend_simple_query

The intellisense is excellent and queries are executed as soon as the query is syntactically correct. I discovered quite a bit with the intellisense alone but the best way to learn is to actually take a look at how the NDepend product has been built. I mentioned that all of the reports, metrics and best practice rulesets are built around this features so take a poke around and learn by example.

If you go to NDepend > Windows > Rule Explorer you be presented with a comprehensive set of default rules which have been built around (from what I can tell) Microsoft’s own coding guidelines.

The left hand column contains groups of rules and the right hand column lists all the rules. If you click on a rule it will bring up the related CQLinq query which you’ll find is extremely similar to the inline C# documentation format. You can see below there’s a <name> tag which, obviously, gives the rule a name and further down there’s a description tag. There’s nothing foreign here and I love how familiar this feels. The learning curve is low.

ndepend-ruleset-sample1
Types too big rule

Browsing the groups and rules is the best way to learn about what is possible and use the samples to build up more complex queries of your own.

ndepend_simple_query2
Types too big CQLInq query

Final words

If you are considering using NDepend at work you might find the 14 day trial period to be a bit short so be sure to set aside some dedicated time to reviewing the tool. If you run out of time and ask for an extension I’m sure there won’t be any issues. I’m lucky enough to have been given a license by Patrick Smacchia to review it and I plan on using NDepend to its full potential. It’s certainly going to keep me busy for the next few months and will consume quite a bit of my free time. It’s my personal code review bot.