Sunday, January 6, 2013

Code Quality - Code Metrics for C# using Sonar

What is Sonar - www.sonarsource.org?

Sonar is an open source tool for analysing, tracking and communicating software metrics for software projects in various languages. Sonar is cross-platform and capable of reporting on a number of languages  including java, c#, c++, javaScript, groovy, etc. The reporting tool is a web-driven application with configurable dashboards. The dashboards communicate code coverage, rules violations, code complexity and can be extended via a large library of free plugins.

Tracking of metrics is accomplished via relational database. Sonar supports the big sql database management systems without much effort. Sonar can easily be integrated into Jenkins/hudson as part of your Continuous Integration process.

A demo of some projects analized with Sonar can be found here: http://nemo.sonarsource.org/ 

More information on sonar can be found here: www.sonarsource.org

Software Metrics Background - Unit Testing in C# and Visual Studio

Software Metrics are a good for managing code quality over time. One of the metrics we hear a lot is Code Coverage - the lines or units of code covered by unit tests.  Many more metrics exist that can analyze code and detect overly complex code. We can also analyze code and use software to enforce code conventions, best practices and detect code smells. Code smells are coding practices that are not necessarily errors but are error prone. These all present opportunities for refactor and increased code quality.

For the .Net world, a number of options already exist and have for some time. FxCop for example, can do the rules analysis for code conventions and some code smells. Visual Studio 2010 Pro and up ships with code analysis tools for detecting overly complex code (Cyclomatic Complexity) and reporting on unit coverage. Other options exist too for Visual Studio integration via plugins. Not to mention what 2012 ships with. Keep also in mind that Team Foundation Server can integrate all this as part of a Continuous Integration process. TFS is clearly documented and very easy to use. It is tightly integrated with Visual Studio.

So before you jump too deep into Sonar - Visual Studio already has most of what you need - the exception is web-based reporting. Sonar is the perfect tool if leadership or upper management needs to see this information. You need to weigh the the time investment in Sonar to get its reporting capabilities vs. using Visual Studio, which with combined with FxCop, will get you all the metrics you need to start monitoring your code quality.

The catch with Visual Studio of course, is that to use its canned options, you may not use NUnit (if you know a way do let me know). If you are writing new code - do not use nUnit. You get tight and free integration using Visual Studio’s unit testing libraries and simple - no config debugging. Reason number two: Code coverage. Getting code coverage for .Net projects using NUnit is not cheap.

For a team this means third party licenses for something like NCover or spending the hours to chase down and learn a free command line tool like OpenCover. Your options are few. Since VS2010 introduced such clean and tight integration of Code Metrics, third party development of unit test platforms, test runners for visual studio has mostly dropped off the radar. Sure there are some products but they are no longer the ‘normal’ development path for new dev projects in .Net. DotCover from JetBrains is a good one if you are looking for a runner for NUnit. I still advise you bite the bullet and convert the NUnit tests to MS Test.

If you already are using NUnit you still have some thinking to do. You need to weigh the cost of converting your unit tests to MS Test Unit Testing. You also need to weigh the cost of future productivity. If you aren’t doing Continuous Integration (why?) and not doing any static code analysis it probably makes sense to convert your unit tests and use the offerings from Microsoft. If you already have a bunch of time invested in Continuous Integration of your nUnit tests - maybe not.

Now having said all that, here’s the nuts and bolts.


Setting up Sonar for C#

First you’ll need some prerequisites.

1. A recent JRE. 
2. mySql (or some other sql server). The docs for Sonar clearly map how to use mySql so it is the path of least resistance.
3. Visual Studio 2010+ or a recent Windows SDK 7. You need access to msbuild.
4. A Code Coverage tool -  OpenCover, dotCover or NCover. I have not had good luck with OpenCover though others have. 
5. Gallio - a test runner. http://www.gallio.org/


Installing Sonar

For use in C#, sonar comes in three pieces. Sonar itself - the web-based dashboards. sonar-runner - a command-line client that launches the analysis. The C# Ecosystem Plugin - this consists of several plugins specific to the C# world and are used for configuring .net, Silverlight requirements, test runner locations and coverage analysis locations.

Sonar

  1. Download Sonar: http://www.sonarsource.org/downloads/
  2. Extract the contents to a location in which Sonar will live and execute from.
  3. Setup the Database parameters:
  4. locate the file and edit the file conf/sonar.properties. You will modify the database connectivity parameters below:
  5. sonar.jdbc.url: the URL of the database
  6. sonar.jdbc.driver: the class of the driver
  7. sonar.jdbc.user: the username
  8. sonar.jdbc.password: the password
  9. Create the schema for your DB. I used mySql. https://github.com/SonarSource/sonar/tree/master/sonar-application/src/main/assembly/extras/database/mysql
  10. Starting Sonar on Windows: Launch bin/windows-x86-32/StartSonar.bat. You can also setup Sonar to run as a service and start automatically using the scripts in the bin directory.
  11. Point a browser to http://localhost:9000/


C# Plugin Ecosystem

  1. The site for this plugin is here and includes the download. http://docs.codehaus.org/display/SONAR/C%23+Plugins+Ecosystem
  2. Download and extract the plugins to SONAR_HOME/extensions/plugins
  3. Restart sonar. (Point a browser to sonar and login to access the menu to do this.)
  4. At a minimum - configure the Gallio Plugin. This is done by logging into the Sonar website.

Sonar-runner

There are two ways to kick off sonar analysis, via Maven and via the sonar-runner client. Since this we are dealing with the .net world it doesn't necessarily make sense to deal with Maven. The biggest trick to setting up sonar-runner is the use of environment variables.


  1. Sonar-runner can be found here: http://docs.codehaus.org/display/SONAR/Installing+and+Configuring+Sonar+Runner
  2. Extract the file to a permanent location.
  3. open and edit the configuration file $SONAR_RUNNER_HOME/conf/sonar-runner.properties where $SONAR_RUNNER_HOME is the path to your sonar-runner directory.
  4. Key elements to change are the database driver and the source directories if your structure is different.
  5. Create an environment variable named SONAR_RUNNER_HOME and point it to $SONAR_RUNNER_HOME
  6. Add $SONAR_RUNNER_HOME/bin to your path Environment variable.
  7. Test sonar-runner by opening a command line interface (Run -> cmd) and typing sonar-runner <enter>. You should see some tips for usage.

Sonar-Project Properties File

Sonar-runner requires the use of a sonar-project.properties file. This file should live in the same directory as the Visual Studio Solution file you want to analyze. Here’s a minimal properties file:

# required metadata
sonar.projectKey=my:project
sonar.projectName=My project
sonar.projectVersion=1.0

 # The value of the property must be the key of the language.
sonar.language=c#


Kicking off Analysis

Analysing a project is pretty simple. Simply navigate to the directory and execute the command: sonar-runner
You’ll want to fire this off at the end of a Build on a build server. Jenkins/Hudson has plugins to assist in this, though I had no luck in actually using the plugins. I used Power Shell to launch it. Those of you using TFS will be able to launch it as well, just with the groovy TFS mechanisms.
Enjoy :)



References

http://sonarsource.org
http://nemo.sonarsource.org/
http://docs.codehaus.org/display/SONAR/Installation+and+Upgrade
http://docs.codehaus.org/display/SONAR/C%23+Plugins+Ecosystem
http://docs.codehaus.org/display/SONAR/Installing+and+Configuring+Sonar+Runner