4/06/2012

Static Code Analysis based on NDepend

This is the eleventh blog of a series of posts about the topics Continuous Integration and Continuous Delivery. It explains how important continuous integration is, to deliver software in short iterations to the customer with a high quality standard.

The static code analysis rules from Microsoft, which I introduced in the last post, are a great and easy start to find common problems in your code like memory leaks, security holes or application crashes. As soon as you want to define own customized rules and analyze your code very deeply, you should take a look at NDepend. It is an amazing tool which is quite easy to use and gives you great information about the quality of your code by analyzing the dependencies of every single line. Besides that, NDepend supports an own easy SQL-like query language to select the important information from the code analysis. And after all it can be easily integrated into the CI build to execute the defined queries and check if any of them are violated.

In the following post I am going to explain how to write own queries with NDepend and integrate them into the TFS build workflow.

Set up NDepend

First of all you have to download NDepend. The installation package comes with a Visual Studio Add-In which you should install. After that a new menu entry is available in the Visual Studio as well as a status icon in the bottom right corner. Load your current solution and select the NDepend menu entry "Attach new NDepend Project to current VS Solution". It is important that you build your solution before you use NDepend because the analysis is based on the created assemblies. After you attached NDepend to the solution an analysis will run and show the following web page:


You should spend some time on this web page and study all the information and metrics you get from NDepend. There is a Dependency Graph and Matrix as well as more than 80 code metrics like complexity, maintainability index or lines of code respectively intermediate language. You can easily identify the parts of your code which are used heavily (Type Rank metric) and should be tested more carefully because bugs in these components would have a higher impact. All the NDepend metrics are explained in detail on the page NDepend Code Metrics Definitions. The areas on the NDepend web page are defined in the CQL Query Explorer. Out-of-the-box NDepend already delivers hundreds of predefined queries to analyze your code deeply.


Write your own queries

NDepend is a powerful and complex tool to execute static code checks. But it also allows to define an own rule set by using the code query language (CQL). You can easily adapt the existing queries or just create your completely customized ones. Because of the SQL-like syntax it is really easy to understand.

The following query, for instance, selects all the methods which have more than 20 lines of code (comments and empty lines are not counted).
SELECT METHODS WHERE 
NbLinesOfCode > 20 
ORDER BY NbLinesOfCode DESC

Besides such general queries it is of course also possible to write specific queries for your solution. This query selects all assemblies which directly reference the data access component (DepthOfIsUsing "ASSEMBLY:DataAccess" == 1) but are not the business logic (!NameIs "BusinessLogic"). This can detect, for example, if the data access is used directly by the presentation layer.
SELECT ASSEMBLIES 
WHERE DepthOfIsUsing "ASSEMBLY:DataAccess" == 1
AND !NameIs "BusinessLogic"

Integrate NDepend into TFS Build

After you defined all your NDepend rules, it would be great if code which violates the rules cannot be checked-in anymore. Therefore, you have to flag first the queries you want to cause an error. First of all, the query has to give a warning if a certain threshold has been reached.

In the following example a warning is shown if just one method exceeds 20 lines of code.
WARN IF Count > 0 IN 
SELECT METHODS WHERE 
NbLinesOfCode > 20 
ORDER BY NbLinesOfCode DESC

Additionally, the rule has to be marked as critical to make the build fail. There is a red button in the upper right corner:


After you defined all your rules, limits and importance of the rule, the build has to be configured to fail in case of check-ins which do not fulfill these rules. First of all, enable the gated check-in feature that the bad code is not committed in the source control. An NDepend Activity is available on codeplex and has to be integrated in the TFS 2010 Workflow Build. (see also Integrate NDepend with TFS)


How to improve old legacy code step-by-step

All of these code checks are great if you introduce them before you actually write code. The problem is just that this is not all the time the case. In most of the cases an old legacy system with a lot of code already exists and should be improved. This can be usually just being done step-by-step.
Think about introducing a rule that every method should be a maximum of 20 statements long. With legacy code and thousands or ten-thousands methods introducing this rule is nearly impossible. But therefore NDepend provides a great feature to apply the rules just for changed code. This makes it possible to define strict rules and introduce them step by step. Every check-in makes the code better than before and even huge and complex systems can be improved over time.


Summary

NDepend is a great and extremely powerful tool to analyze your code. You can easily write your own queries and integrate them into the build. This saves a lot of time during the architecture, design and code review because the most common errors can be already detected before the code is actually check-in. Afterwards it is usually extremely difficult and can cost a lot of money to clean up and repair the bad code.

Hint: Try to identify after every code review the common errors and write a rule which detects them in the future.