Thursday, February 26, 2009

DeepZoom Your Code Quality With NDepend

I've recently started playing with NDepend again.  This tool is a sort of data mining utility for your code.  Feed it your assemblies and it can tell you almost anything about them.  Using a custom query language with a SQL-like syntax, you can dig into all sorts of metrics and useful information. Out of the box, it ships with tons of useful queries for common code problems. 

I ran some of our code through it and got dinged on some of the code complexity queries:

 image

In this case, I had several huge methods that needed to be broken up and optimized.  Thanks to NDepend's prodding, I spent some time refactoring using ReSharper, and whittled those down to 0s:

image

That's helpful, but not nearly everything that NDepend can do.  For example, the code I'm testing with is involved in some multithreading, so with a little digging through the docs, I came up with this query to show all methods that change state (besides property and event setters), but don't use any locks:

WARN IF Count < 0 IN SELECT METHODS WHERE
!IsDirectlyUsing "System.Threading.Monitor" AND ( ChangesObjectState OR ChangesTypeState ) AND
!IsConstructor AND !IsClassConstructor AND !IsPropertySetter AND !IsEventAdder AND !IsEventRemover

This doesn't guarantee thread-safe code, but it definitely helps drill down to potential problem areas.

Another area I can see us using this in is to provide metrics for our customers.  Generally they are not concerned with things like Cyclomatic Complexity, but some simple numbers may be useful.  We use FinalBuilder, so it's possible we could run NDepend's console utility to roll the numbers into some XML and publish to their customer wiki.  For example, here's a quick query to spit out the total number of tests for a project:

SELECT METHODS FROM ASSEMBLIES "TestAssemblyName" WHERE HasAttribute "NUnit.Framework.TestAttribute"

Once we get a customer set up with these metrics, we'll post more about how to automate that.  Until then, go check out NDepend!

No comments: