Using NDepend to identify areas of interest in a code base.
If you’re working on a project of any size, and unless the entire team is made of uber-developers, code reviews are necessary if you’re going to end up with something that can be maintained. And, the larger the project, the more of a chore a review becomes, particularly if you don’t run a tight ship and perform it after every significant change. Sure, you can always just look at the source control DIFFs, but even in this way, it can be difficult to inspect a large change set for items like method complexity, or the proper use of accessors, or what have you. Even if you can handle that, it takes time, and is, on occasion, quite mind-numbing.
I’ve been using the excellent NDepend. This neat application does a whole lot of stuff, but I’m going to focus mainly on the code analysis queries which allow us to generate reports on the code base. This lets you highlight problem areas a lot more quickly, leaving more time for proper developer activities, like coding and drinking coffee.
In the image above, we have a list of query categories (left) and the actual queries (right) along with the number of instances which break the rule defined by the query. As you can see, the current family of queries describes any oversized methods, methods with poor comments… sound familiar? These code smells are the things you’d usually need to dig up in a review.
CQL – The code query language
Even though NDepend comes with a large pool of useful queries, it’s entirely possible that your situation demands a different set of rules, or maybe your standards require different constraints. This is not a problem – all the standard queries can be modified, and you can, of course, add your own. All queries are written in CQL, a query language (unsurprisingly similar to SQL) which queries code metrics. The CQL specification is well documented, so anyone with a basic understanding of any query language should have little trouble running with it.
For a simple example, let’s modify the naming convention rules. One of the default rules states that instance fields should be prefixed with an “m_”. Now, I don’t like that style very much; I prefer to have instance fields look just like any other field (starting with a lower case) – my argument being that, if you need a prefix to distinguish between instance and local fields, you’re probably not naming them clearly enough. Anyway. The default rule looks like this:
The <Name> element in the comment is used to define the text that will appear in the report. In this case, we can see that we’re looking at field names, and we’re ignoring static, literal, and auto-generated members. The line we’re interested in is the first one: !NameLike “^m_”, which will take a regular expression. Modifying it to: !NameLike “^[a-z]” gives us the query we want.
While this is useful, it is by no means big or clever; if you look at the specification for CQL, you’ll realize just how deep the rabbit hole goes. Hopefully, this simple example will at least show you what it looks like, and encourage you to meddle.
While NDepend sports a funky, easy to use interface, if you’re anything like me the lazy part of your brain is probably wondering if there’s a way to avoid having to run the application and press the buttons to generate the report. In fact, NDepend can be integrated with a CI Server quite easily. There have been several good articles about this in the past, so instead of going over it all again, I’ll just point you to Laurent Kemp’s article about TeamCity integration and the confluence page for Cruise Control integration. If you’re really hardcore, you can even run the command line version through Visual studio’s build process, but I find that’s generally overkill.
So there it goes. Along with Reflector and TestDriven.Net, NDepend is one of the most useful tools I found. In the last month, I’ve moved to a Java job (I’m not planning to turn my back on .Net or anything! But do expect a bit more variety in the blog if I do get round to writing more), and I was rather pleased to discover that ol’ coffee-themed has its own version of NDepend in the form of XDepend. I’m sure that will make the transition that much smoother
As usual, any questions and comments are welcome.