I've been giving NDepend a go lately, in part because I've had my eye on it for a while, and in part because Patrick Smacchia offered me free trial of NDpedend Pro recently
I decided to try out NDpedend in a few different scenarios, that relate to different ways I might use it at work, so I spent a few hours with NDepend on three different code bases
- A small code base - ~3KLOC - that I know quite well because I wrote 80% of it.
- A medium sized code base - ~70KLOC - that I also know well because I worked on the team that wrote. But I only wrote a small portion of it myself.
- A small code base - ~5KLOC - that I don't know at all. -I've only had a 10 minute intro to the architecture.
These, IMHO, span a number of scenarios where I might use NDepend: From scenarios where I know the code well, but want NDepend to help keeping myself and my team in check, to scenarios where I am reviewing or taking over an unknown code base, and want NDepend to help me get an overview and to help me drill into problematic areas.
Ok, but lets back up a bit: What is NDepend? -NDepend is a static analysis tool for .NET code that provides metrics like cyclomatic complexity, average and max methods per class, average and max statements per method, assembly dependencies, namespace dependencies and so on. Check the NDepend site for the full feature list.
And what does the pro version offer? -The pro version is an interactive version of the free NDepend. The free version will spit out a report with all the metrics in them, for you to look at, but the pro version integrates with Visual Studio to give you the possiblity to drill into the data, and to modify the metics using the so-called Code Query Language - CQL.
My observations in general from running NDepend on the three code bases listed above:
- NDepend is pretty fast, at least when the code bases are not too big. This is less important if you intend only to run NDepend on your CI server as a late stage step, but if you want to take an interactive approach it's crucial.
- The interactive drill down capabilities of the pro version are enticing...is that good or bad?...for me, on the one hand, it meant that I actually discovered more about the code bases than I think I otherwise would have, on the other hand, I also spent more time than I planned to.
- The default NDepend analysis is expressed in CQL queries that can be modified in Visual Studio, which I used to tighten some of the metrics. Doing that was dead easy, and is a real benefit because it allows you to go with your own standards.
- The default warning levels for the different metrics are, in my opinion, not tight enough. I especially want fewer statements per method and lower cyclomatic complexity. So that's sometihng I be tweaking in future uses of NDepend.
My observations relating specifically to the three code base above are:
- NDepend did not tell me anything I did not know about this code base. -But it's also a degenerate case becasue the code base is so small and because I wrote most of it myself, so I have all it in my head anyway.
- This case is a lot more interesting: The code base is of a size where it is hard to hold it all in your head, and it was written by a team, so no one person has actually looked deeply at all the code. For this code base NDepend gave me some interesting insights:
- NDepend was able to produce a very sensible list of methods and classes that need refactoring. About half of them I was aware already, but the other half I wasn't.
- NDepend was also able to pin point to major areas where the problematic code was concentrated. I sort of knew those were pain points, but NDepend made it a lot clearer. That's a big win.
- NDepend quickly produced a complete dependency graph, with a half hour of moving boxes around, deleting irrelavant boxes and so on I had a useful diagram of the dependencies in the project. That was actually something we had wanted for a while, but hadn't gotten around to, so that was a nice by-product.
- The third code base was another small one, but one I didn't know. In this case NDepend gave me:
- A quick overview of the internal and external dependencies. Again in a fairly clear and readable diagram that the teams tech lead was able to confirm quickly
- Pinpointed the two methods that very overly complex (2 aren't many BTW - that team did a good job, so far)
- A single instance of a cyclic namespace dependency - that the teams tech lead wasn't aware of