Unit Tests Measure Health But Only nDepend Measures Quality

Often times in the development of software, it is important to know the health of a system at certain milestones.  These generally take the form of developer-led unit tests, tests run on nightly builds of CI servers or automated or manual tests lead by test personnel.  Though these tests serve to show the operational state of a system to measure the level of undesirable traits, they don’t really indicate how well a system is constructed.  By this I mean:

  • were coding guidelines followed?
  • are multiple classes per file?
  • are there any methods too large?
  • are there any parts of the code that is too complex?
  • are there any methods with too many parameters?
  • are there any classes with excessive methods?
  • is the UI layer directly using DB types?
  • is there a sign of partitioning the code base through many small assemblies?

The answers to these questions not only impacts the immediate code base but also medium to long term maintenance of a system. There is an immediate concern because the system is in the process of being built and there might be cases where new developers are brought on board to help out.  Problems with the code hinders not only immediate development but also future maintenance.   Philosophies such as "YAGNI” or “just ship it” are detrimental to the quality of the code and not particularly mindful to future coders who must return to it in the future.

The popularity of code reviews serves to address many of the questions posed above but often times such reviews are subjective, instigate debate, the playing of many trump cards and conclude in an unsatisfying work by the part of the author who merely had noble aspirations to the business.

At a company I once worked for, I had a code review where the reviewers claimed that my work was more complex.   Luckily I knew about static code analysis tools and a measurement called cyclomatic complexity (CC).

Cyclomatic complexity is a software metric used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program’s source codeWikipedia

Each method’s if, while, for, foreach, case or continue statements contribute to the number of CC and the number should be under a certain threshold.

Through tooling I was able to show that not only were my changes under the CC threshold but it had actually reduced it from what the code base had before.   The tool was able to remove subjective opinion from the equation, convince my peers and my code passed review.  Such a tool is nDepend and it does a lot more than settle code review debates.

nDepend

nDepend is a static code analysis tool that can either run as a stand-alone app, integrated with Visual Studio or run from the command-line on build servers.  nDepend comes out-of-the box with many useful analysis tools to measure the quality of your codebase.  If you have ever played with the Code Analysis feature in Visual Studio you will understand the concept, however nDepend goes much further.

nDepend stand-alone application:

ndepend 01

nDepend running in Visual Studio.  nDepend creates its own .ndproj files that can be optionally attached to the .sln or the users file depending on whether everybody has a copy of nDepend or not.  After analysing a solution nDepend can show a dashboard showing the current and historical analysis results.  Here you can see that I have nDepend analysing an old Raytracer solution of mine. It’s a single project experimental app but you can see that there are some issues in creating an app this way.  I have two analysis sessions but because there’s been no changes no deltas are shown and the chart is flat.

ndepend vs 01

Everything in the dashboard is clickable.  Clicking the red “3” under Rules.Critical we see:

VSCriticalRules

…specifically:

criticalrules01

Double-clicking Avoid methods too big, too complex I can drill down-into which methods are causing this issue:

Methods too big

Finally double-clicking an entry jumps to the source code.  Very handy!

shade

Rules

nDepend analyses your code via rules written in a LINQ-looking language called Code Query Language or CQLinq.  Rules are grouped by category and can be optionally disabled if you so desire.  nDepend allows you to write your own rules which becomes very useful later during CI server builds and even gated check-ins.

API

Apart from determining whether code is violating certain rules or not, CQLinq is also useful to extract information from the code base.  For example you might want to determine requirement implementation coverage in a project’s code base.  nDepend allowed us to do just that by having the testers flag parts of their code with certain requirement markers that we were able to then extract via the nDepend API in a tool of our creation.  This gave us an accurate view of not just how development is progressing but also how complete tests were.  For businesses following application lifecycle management (ALM) processes this was a brilliant feature.

Visualisation

This is an area where nDepend really shines.  It includes many highly useful and informative graphs that can quickly indicate problems or assist in the understanding of a system’s structure.  One such graph is the Code Metrics View.  This view can then show specific flavours such as Cyclomatic Complexity (both source code and IL), # Methods, # IL Instructions and more.  For the CC view we can see the relative sizes of methods (box size) and CC (colour).  This highlights an important point – just because a method may have a large number of lines doesn’t necessarily mean it will have a large CC or vice versa.  The MainForms’s InitializeComponent is relatively large at 283 lines but because there few paths through the method (actually only 1) it has a low CC.

Conversely, my Raytracer’s Shade() method has 51 lines and a high CC 13.  The Screen() method right next door (same size box) has 48 lines at 7 CC.

CM View 01

I just love the tooltips in nDepend.  They are very rich with lots of useful information.

Shade tooltip

nDepend also has a suite of Dependency Graphs that allows you to visualise the structure of your system in many ways.

aircon dependency graph

One of the more interesting graphs is the Dependency Matrix, a view that is very important for highlighting any architectural problems with your code with respect to say circular dependencies or tight-coupling.

Depend Matix 01

Historical Analysis

As mentioned, nDepend can display historical analysis and additionally compare the current state of the code with prior baselines.  This gives a strong and immediate indication as to whether the quality of the code is improving or not.   It is certainly strong evidence that should be used in any code review.

Conclusion

nDepend is an extraordinarily powerful tool that should be part of any due-diligent developer’s toolbelt. It’s approach to static code analysis is unrivalled, certainly in its ease of use and richness of presentation.  It has considerable more features than what is described here.  I urge you to try out their demo and point it at your own projects.  You may be shocked at what you might find.

Disclaimer:  the author was provided a copy of nDepend for the purpose of this review.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.