Thursday, December 26, 2013

NDepend: Code Quality Regressions and Ensure Quality from Now!

In the previous article I have described basic features of NDepend. This one is dedicated to Code Quality Regressions and Ensure Quality from Now. In a few words, you can set a project baseline and compare different analysis results, it can show how the code quality was changed during specified period of time.

Setting baseline for comparison

The settings are accessible from menu NDEPEND => NDepend Project => Edit Project Properties => Analysis tab. There are two baseline options: one for comaring in Visual Studio UI, another one for reporting. You can compare with previous analysis of the current project or with different NDepend Project you have performed analysis on. In the selected project you can also choose a specific analysis to compare with.

Comparison features in NDepend UI

Compare older and newer version of source file

If you right click on a class or a method that has been changed, we can see an appropriate menu item:

The result is shown in standard Diff window with older version on the left side and newer version on the right:

Select code units what was changed from Solution Explorer

If we click on a project, folder or file in Solution Explorer, we can choose what kind of changes we would like to see as a result of this analysis:

Here we can see that the previous comparison is a feature that is included in any source control system. This one is something deeper as it uses static code analysis for versions comparison purposes:

Search code units with particular kind of changes globally

There is a special search window accessible from the main VS menu NDEPEND => Compare => Search some particular Code Elements Changed, where you can choose a special kind of changes and select necessary code elements throughout the whole solution:

Comparison features in NDepend Reporting

Queries and Rules Explorer as well as NDepend HTML Report will contain 3 specialized set of queries:

  1. Code Quality Regression
  2. API Breaking Changes
  3. Code Diff Summary

Code Quality Regression

It contains the following set of rules:

The selected rule "From now, all types added or refactored should respect basic quality principles" is represented by the following CQLinq query:

// From now, all types added or refactored should respect basic quality principles
warnif count > 0 from t in JustMyCode.Types where

// *** Only match new or modified types since Baseline for Comparison ***
(t.WasAdded() || t.CodeWasChanged()) &&

// Eliminate interfaces, enumerations or types only with constant fields
// by making sure we are matching type with code.
t.NbLinesOfCode > 10 &&

// Low Quality types     Metrics' definitions are available here:
(  // Types with too many methods
   t.NbMethods > 20 ||

   // Types with too many fields
   t.NbFields > 20 ||

   // Complex Types that use more than 50 other types
   t.NbTypesUsed > 50
select new { t, t.Methods, t.Fields, t.TypesUsed }

// This rule warns if a type with
// low-quality has been added or refactored.

This is very cool rules, I would say it exposes basis "Everything you touched should smell of roses". It means you may get a legacy project, full of smells, so making it perfect will be really worthless, but any new code that you add or any old code that you refactor should follow these quality rules from now. Sometimes it's difficult to follow as during refactoring you can end up with too long chain of types and methods to fix, but I find this very helpful, especially when you integrate NDepend to your build and continuous integration system.

API Breaking Changes

It shows any changes, that was made to any publicly visible code constructions. Here is the set of rules:

Here is a query sample to "API Breaking Changes: Types":

// API Breaking Changes: Types
// This rule warns if a publicly visible type is 
// not publicly visible anymore or if it has been removed.
// Such type can break the code of your clients.

warnif count > 0 from t in codeBase.OlderVersion().Application.Types
where t.IsPubliclyVisible && 

     // The type has been removed and its parent assembly hasn't been removed ...
     ( (t.WasRemoved() && !t.ParentAssembly.WasRemoved()) ||

     // ... or the type is not publicly visible anymore
       !t.WasRemoved() && !t.NewerVersion().IsPubliclyVisible)

select new { t,
             NewVisibility = (t.WasRemoved() ? " " : t.NewerVersion().Visibility.ToString()) }

Code Diff Summary

This long set of rules contains comprehensive analysis of changed and added source code:

The selected query sample "Third party types that were not used and that are now used" is pretty simple:

// Third party types that were not used and that are now used
from t in ThirdParty.Types where t.IsUsedRecently()
select new { t, t.Methods, t.Fields, t.TypesUsingMe }

Custom set of rules "Code Improvements"

Sometimes it's interesting to know how the existing code was improved, because you can refactor a lot, but you cannot go too deep with this, so you still have to leave some traces, like changed types and methods and so on. Considering that NDepend shows only regressions, one can have feelings that everything just got worse. Thus I suggest a list of CQLinq queries described in the article NDepend: Set of Rules to Show how Code Quality Was Improved.

New Features in NDepend 5.0

New version of NDepend, NDepend 5.0 contains even more interesting and useful features in sense of comparing analysis results, like Recent Rules Violations, Trend Monitoring and others.

No comments:

Post a Comment