This is the 3rd post of this series on Getting Started With Continuous Integration For Your .NET (C#) Projects.
In the 1st post, we investigated on how to build your .Net project in Jenkins using the MSBuild on every code checkin.
In the 2nd post, we investigated on how to integrate running unit test in the build using the command line tool - mstest.exe.
In this post, we will explore how to integrate Sonar, the open platform to manage code quality, with Jenkins.
If you ask a software engineering manager to list the items that he/she cares most about a software project? One of the items must be software quality. But, the question is how to measure the software quality, what are the metrics to measure software quality? The obvious answer would be customer satisfaction, the number of bugs found by QA team. However, those metrics are only available after the software is delivered to customer or QA team, which will be very late for development team to improve. If development team could get software quality metrics feedback at the early phase, continuous improvements can be made before the software is delivered to customers. That's the goal Sonar is trying to achieve.
Sonar analyzes the source code and presents 7 axes of code quality for your software projects as the software is being developed. It gives development team early feedback on the code quality.
Note that, Sonar focuses on source code, so it doesn't do anything about whether the software meets customers requirements. It helps you to write code right, but not helps you write right code.
The axes of code quality sonar analyze includes:
Below is the high-level Sonar architecture from the Sonar official website.
Sonar involves 3 major parts:
According to the architecture, sonar analysis doesn't provide real time feedback as it takes time to analyze. In general, making the sonar analysis as a nightly job is a good practice.
Sonar employs the plugins-based architecture which has built-in support for Java. The C# support is done by the C# Plugins Ecosystem. Let's take a look at the overview of the C# plugins ecosystem.
Introducing the C# Plugins Ecosystem
The C# Plugin Ecosystem (see: http://docs.codehaus.org/display/SONAR/C-Sharp+Plugins+Ecosystem) doesn't analyze the code by itself, but it invokes external tools to do the job. Therefore, the C# plugins works as a bridge between sonar and the external tools. It has the following major components. Descriptions are copied from the official website with some further explanations.
The StyleCop, FxCop and Gendrame should be easy to setup without any tricks. I'd like to explain the relationship between Gallio and PartCover a little bit. They work together to run the test cases and calculate the code coverage. Gallio is the tool to launch the real test runners such as mstest.exe to run the test cases. PartCover is the cover engine which calculates the code coverage details while the test cases are running. Refer to the C# Plugin Ecosystem page on how to install the plugins and the required tools. Be sure to install the tools version that are supported.
Note: the code coverage is supported in visual studio 2010. You could enable it while running the test cases. However, there is no sonar plugin to marry with the coverage results generated by VS2010.
Enable Sonar for the C# projects
To analyze C# projects using the sonar C# plugins, a sonar-project.properties must be created in folder where the .Net solution file is located. The file defines the attributes for the sonar analysis and the C# plugins. Here are the things that you should know before creating your own sonar-project properties.
Below is example sonar-project.properties file for my C# project (sensitive information removed).
#################################################################################### # The properties below are for the sonar project, not pertain to the C# plugins #################################################################################### # Project identification # This defines a unique key for the project that will be created in the sonar. Use the java package naming convention to define it. sonar.projectKey=com.mycompany.myproject # The projectVersion can be ovrriden in Jenkins with the build number sonar.projectVersion= Manual Analysis # The project name that will be displayed in the Sonar web interface, make it meaningful. sonar.projectName= My Project 1 # Info required for Sonar sources=. # Tell the source code is C#. sonar.language=cs # Source Encoding sonar.sourceEncoding=UTF-8 #################################################################################### # The properties below are for the C# plugins #################################################################################### # Specify the assembly to analyze. It could point to the build output folder. # Note: the absolute path is used here as relative path doesn't work for me. sonar.dotnet.assemblies = $(SolutionDir)/MyProject/bin/x86/Release/MyProject.exe # Specify the tests projects so that the code in the test project will not counted as the production code. # Note the separator is ';', and there is a typo in the key but do not attempt to correct it. sonar.donet.visualstudio.testProjectPattern = *MyProject_UnitTest;*MyProject_UAT # Sepcify the test assumblies which include the test cases, i.e. the build output of the test projects. # Note the separator is ','. This allows us to have 2 test projects. sonar.dotnet.test.assemblies = $(SolutionDir)/MyProject_UnitTest/bin/Release/MyProject_UnitTest.dll,$(SolutionDir)/MyProject_UAT/bin/ReleaseMyProject.dll sonar.gallio.runner = IsolatedAppDomain # Ignore the generated files to avoid bias on the result # Note the separator is ',' sonar.exclusions = **/Generated.cs,**/Constants_Dynamic*.cs
Trouble Shooting
Possible Issues
Integrate with Jenkins
If the sonar analysis can be successfully run with the Java runner, it proves that the configurations are correct. We can create a job in Jenkins to run the sonar analysis nightly. To integrate Sonar with Jenkins, the sonar plugin for Jenkins must be installed. After that, a new step in the job can be created to start the sonar analysis. See figure below:
A few things to note:
Summary
We've gone thru 3 major topics about continuous integration for .Net project, building the project, running unit tests and running the sonar analysis. With those setups, we could get early feedback on each code checkins.
The 3 topics represents different level of feedback, the lowest level is the project should be built without any compilation error, the 2nd level is the basic unit test should pass, and the 3rd level the code coverage and other code quality metric measured by sonar. We could get some confidence about the code quality and the changes made, but we need more. We need to know whether the software meets the customer requirements. That will be my future focus and interests.
Now this is not the end. It is not even the beginning of the end. But it is, perhaps, the end of the beginning (By Winston Churchill).