Automatische Qualitätskontrolle für C# und Visual Studio

Mit SonarQube in the Loop
Kommentare

Fehler, die der Kunde im laufenden Betrieb findet, sind teuer. Fehler, die in der Entwicklungsphase gefunden werden, sind günstiger zu beheben. Am besten wäre es, Fehler von vornherein zu vermeiden. Ein Schritt in diese Richtung ist die Beachtung von Best und Worst Practices für den C#-Code. Wurden wirklich alle IDisposables disposed? Entspricht der Code den Coding Guidelines und ist dadurch leicht lesbar und wartbar? SonarQube nimmt sich genau dieses Problems an.

Der Quellcode wird nach Unsauberkeiten durchsucht, die Ergebnisse werden zentral gesammelt und über ein Webportal zur Verfügung gestellt. Seine Wurzeln hat SonarQube in der Java-Community. Mittlerweile ist das Werkzeug aber auch gut in Visual Studio, VSTS und TFS integriert. In diesem Artikel erfahren Sie, was SonarQube kann und wie Sie erfolgreich damit starten.

Automatische Analyse der Quellcodequalität ist in Visual Studio schon lange ein Thema. Sie haben in der Vergangenheit vielleicht selbst Tools wie StyleCop, FxCop oder Visual Studio Code Analysis verwendet. Einer der Nachteile dieser Tools ist, dass sie nur eine Zeitpunktbetrachtung erlauben. Wäre es nicht schön, wenn Analyseergebnisse zentral gesammelt und mit einer leicht zugänglichen Weboberfläche über einen längeren Zeitraum betrachtet werden könnten? Genau das macht SonarQube. Microsoft hat 2015 begonnen, in Kooperation mit dem SonarQube-Team das Tool sowohl in Visual Studio als auch in TFS zu integrieren.

Gebotene Funktionalität

SonarQube ist ein quelloffener Server, der so genannte Quality Snapshots in einer Datenbank speichert und eine Webseite dafür anbietet. Dazu gehören Scanner, die den Quellcode analysieren und nach Fehlern oder Unschönheiten („Code Smells“) durchsuchen. SonarQube zeichnet sich durch Erweiterbarkeit aus. Plug-ins sind für die unterschiedlichsten Plattformen und Programmiersprachen verfügbar. Für uns als Microsoft-Entwicklerinnen und Entwickler besonders wichtig: Es gibt Plug-ins für C#, TFS Version Control und Azure Active Directory, die in SonarQube unter Administration über System | Update Center, installiert werden können.

Installation

Es versteht sich von selbst, dass die SonarQube-Dokumentation eine Installationsanleitung enthält. Ich rate jedoch von einer manuellen Installation ab. Es gibt eine wesentlich zeitsparendere Möglichkeit, nämlich die Verwendung des fertigen, offiziellen Docker Images sonarqube. Dadurch erhält man einen fixfertig installierten SonarQube-Server ohne selbst auch nur ein einziges Installationsprogramm starten zu müssen. Ein docker run-Kommando genügt und schon läuft der Server. Details zum sonarqube-Docker-Image findet man im Docker Hub.

Wer noch keine Docker-Infrastruktur hat, dem rate ich, einen Docker-Host inklusive SonarQube in Microsoft Azure zu nutzen. Der Grund dafür ist, dass Microsoft in Azure eine fertige Docker-Extension für Ubuntu anbietet. Man muss also auch Docker nicht manuell installieren und sich dafür durch die Installationsanleitung quälen. Stattdessen verwendet man die Azure Extension (Anleitung online verfügbar) und kann nach wenigen Minuten Wartezeit sofort loslegen.

Was die Sicherung der Daten betrifft, gibt es ein paar Dinge zu bedenken: SonarQube speichert Daten in einer relationalen Datenbank. Aktuell werden SQL Server, Oracle, MySQL und PostgreSQL unterstützt. Falls Sie meinem Rat folgen und SonarQube in Azure betreiben, können Sie auch Azure SQL Database verwenden. Das hat den großen Vorteil, dass Microsoft den SQL Server für Sie betreibt und auch die Absicherung (z. B. Firewalls) sowie Backups übernimmt.

Das Docker Image sonarqube verwendet eine eingebettete Datenbank, wenn man nichts anderes konfiguriert. Das ist keinesfalls produktionstauglich! Verwenden Sie unbedingt eine Datenbank außerhalb des SonarQube-Containers. Beispiele dafür wären die oben erwähnte Azure SQL Database oder getrennte PostgreSQL- oder MySQL-Docker-Container (offizielle Images postgres und mysql in Docker Hub verfügbar).

SonarQube speichert Konfigurationsdateien im lokalen Dateisystem ($SONARQUBE_HOME/data und $SONARQUBE_HOME/extensions). Falls Sie das Docker Image sonarqube verwenden, empfehle ich, diese Verzeichnisse auf ein Verzeichnis des Docker-Hosts zu mappen. In Azure würde ich dafür eine eigene Data Disk in Azure Storage anlegen, um im Fall des Falles die OS Disk neu erstellen zu können, ohne die Konfiguration von SonarQube zu verlieren.

Der Vorteil, den man also beim Betrieb von SonarQube in Azure hat, ist, dass man sich so gut wie nicht mit dem Installieren und Warten von Servern auseinandersetzen muss. Ubuntu, Docker, SonarQube, Datenbank und Data Disks stehen fertig zur Verfügung und werden von Microsoft ausfallsicher betrieben.

docker run -d 
           --name sonarqube 
           -p 9000:9000 -p 9092:9092 
           -v /datadisks/disk1/sonarqube/data:/opt/sonarqube/data 
           -v /datadisks/disk1/sonarqube/extensions:/opt/sonarqube/extensions 
           -e SONARQUBE_JDBC_USERNAME=mydbuser 
           -e SONARQUBE_JDBC_PASSWORD=mydbpassword 
           -e SONARQUBE_JDBC_URL="jdbc:sqlserver://...sql-connection-string..." 
           sonarqube

Für Docker-Neulinge habe ich das docker run-Statement zum Starten von SonarQube in Listing 1 zusammengestellt. Es enthält das Port-Mapping für die Standardports von SonarQube (9000 und 9092), die Volume-Mappings für die Konfigurationsdateien und die Umgebungsvariablen für die Verbindung mit einer externen Datenbank wie Azure SQL Database. Sobald SonarQube läuft, kann man sich mit dem Browser auf den Port 9000 verbinden und hat das Webportal von SonarQube vor sich.

Absicherung von SonarQube

Nach der Installation von SonarQube kann man auf den Server ohne Benutzer und Passwort zugreifen. Darüber hinaus haben Benutzername und Passwort für den Administrator-Benutzer den Wert admin. Diese Einstellungen müssen unbedingt gleich nach der Installation geändert werden. Man sollte den anonymen Zugriff verbieten (Abb. 1) und über den Menüpunkt My Account das Administrator-Passwort ändern.

Abb. 1: Authentifizierung erzwingen

Abb. 1: Authentifizierung erzwingen

Des Weiteren empfehle ich, für Produktionsumgebungen den SonarQube-Server über einen Reverse Proxy zugänglich zu machen, statt ihn direkt zur Verfügung zu stellen. Am Proxy sollte ein Zertifikat installiert sein, damit HTTPS statt HTTP beim Zugriff auf SonarQube-Server verwendet werden kann. Wenn Sie meinem Rat folgen und SonarQube in Docker betreiben, steht Ihnen beispielsweise mit nginx ein Reverse Proxy zur Verfügung, der sich wunderbar in der gleichen Docker-Infrastruktur betreiben lässt.

Wer bereits Azure Active Directory (AAD) einsetzt, kann sich mithilfe eines Plug-ins damit bei SonarQube anmelden. Nähere Informationen zur Konfiguration der AAD-Integration findet man auf GitHub.

Scanner

Nach der Installation des SonarQube-Servers legt man sein erstes Projekt an. Das geschieht im SonarQube-Portal unter Administration/Projects/Management. Name und Key des neuen Projekts werden wir in Kürze zum Verbinden des Build-Prozesses mit SonarQube brauchen.

Nach dem Anlegen des Projekts wollen wir es natürlich mit ersten Analyseergebnissen füllen. Dafür müssen wir eine Analyse für unser Projekt laufen lassen. SonarQube bietet dafür verschiedene Scanner an. Eine Liste der Scanner findet man in der Dokumentation. Für Entwicklungsteams im Microsoft-Umfeld ist der MSBuild Scanner besonders wichtig. Auf eine Beschreibung des manuellen Ausführens einer SonarQube-Analyse verzichte ich hier, da in der Praxis immer eine Integration in einen automatisierten Build-Prozess notwendig und sinnvoll ist. Exemplarisch möchte ich SonarQube in Verbindung mit Visual Studio Team Services (VSTS) und dem von Microsoft fertig zur Verfügung gestellten Hosted Build Agent erklären. Natürlich ist die Beschreibung analog auf lokal installierte Team Foundation Server (TFS) anwendbar.

SonarQube Analyse im Build-Prozess

Für VSTS und TFS bieten SonarQube und Microsoft fertige Build Steps an. Man stellt den Begin-Analysis-Schritt an den Beginn des Build-Prozesses und den End-Analysis-Schritt ans Ende. Abbildung 2 zeigt, wie das gemacht wird.

Abb. 2: SonarQube in der „Build Definition“

Abb. 2: SonarQube in der „Build Definition“

Die Konfiguration der SonarQube-Analyse geschieht im Begin-Analysis-Schritt. Als Erstes muss man den SonarQube-Server auswählen bzw. bei erster Verwendung eine entsprechende Verbindung anlegen. Mit Manage kommt man zur Verwaltung der Service Endpoints und kann dort einen Generic Endpoint für SonarQube anlegen. Anschließend gibt man in der Build-Definition noch die SonarQube-Projektdaten ein und fertig ist die Verbindung von Build-Prozess und SonarQube-Server. Abbildung 3 zeigt die auszufüllenden Felder in einem VSTS-Screenshot.

Abb. 3: Build-Prozess mit SonarQube-Projekt verknüpfen

Abb. 3: Build-Prozess mit SonarQube-Projekt verknüpfen

Startet man nun einen Build, läuft der Scanner am Build Agent und schickt die Ergebnisse an den SonarQube-Server. Nach dem Build kann man auf der SonarQube-Webseite nachsehen, welche Qualität der analysierte Code hat.

Quality Profiles, Issues und Measures

Für die Analyse ist natürlich wesentlich, was man als Team als Code Smell, Bug etc. ansieht. In SonarQube legt man das über die Quality Profiles an. Je Programmiersprache wählt man die Regeln, die man aktivieren oder deaktivieren will. Abbildung 4 zeigt, wo das gemacht wird.

Die Auswirkungen der Quality-Profiles-Einstellungen sieht man bei den Issues und Measures und natürlich auch in den zusammenfassenden Dashboards, die man sich frei definieren kann. Die Measures (Kennzahlen) geben einen guten Überblick über die Gesamtsituation im Code. Wie viele Probleme sind enthalten? Wie schwerwiegend sind sie? Hat sich die Situation verbessert oder verschlechtert? Solche Fragen beantworten Measures.

Aus Sicht der Programmiererin oder des Programmierers sind die einzelnen Issues und dabei insbesondere der Bezug zum Quellcode wichtig. SonarQube kann dafür den Quellcode inklusive der gefundenen Probleme direkt im Webbrowser darstellen (Abb. 5).

Abb. 4: C# Quality Profile in SonarQube

Abb. 4: C# Quality Profile in SonarQube

Abb. 5: „Issues“ in der SonarQube-Quellcodeansicht

Abb. 5: „Issues“ in der SonarQube-Quellcodeansicht

Testergebnisse

Neben der Codeanalyse kann man optional auch die Ergebnisse von automatisierten Tests in SonarQube einspielen und analysieren. Es geht dabei einerseits um die Fehlerstatistik, aber andererseits auch um die Codeabdeckung (Code Coverage).

SonarQube kann die vom Visual Studio Test Runner erstellten Reports (.trx-Dateien) unverändert verarbeiten. Die Code Coverage Reports (.coverage-Dateien) müssen vorher in das XML-Format (.coveragexmlDateien) umgewandelt werden. Details dazu können in der Dokumentation nachgelesen werden.

Damit SonarQube die Testergebnisse importiert, müssen entsprechende Optionen beim Begin-Analysis-Schritt angegeben werden. Abbildung 6 zeigt, wo die Optionen eingetragen werden müssen. Um Testergebnisse und Codeabdeckung zu importieren, spezifiziert man die Optionen sonar.cs.vstest.reportsPaths (Pfad zur .trx-Datei) und sonar.cs.vscoveragexml.reportsPaths (Pfad zur .coveragexml-Datei). Leider generiert VSTS für jeden Testdurchlauf neue Dateinamen. Man muss also im Rahmen des Build-Prozesses dafür sorgen, dass die Dateien mit den Testergebnissen an eine definierte Stelle gelangen. Listing 2 zeigt ein einfaches PowerShell-Skript, das exemplarisch die Testergebnisse an eine bestimmte Stelle kopiert und auch die Umwandlung der .coverage-Datei in eine .coveragexml-Datei vornimmt.

Abb. 6: Import der Testergebnisse in SonarQube

Abb. 6: Import der Testergebnisse in SonarQube

Copy-Item (Get-ChildItem "*.trx" -Recurse)[0].FullName TestResults\results.trx
Copy-Item (Get-ChildItem "*.coverage" -Recurse)[0].FullName TestResults\results.coverage
& "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Team Tools\Dynamic Code Coverage Tools\CodeCoverage.exe" analyze /output:"TestResults\results.coveragexml" "TestResults\results.coverage"

Nach dem Importieren der Testergebnisse können diese in der SonarQube-Weboberfläche dargestellt werden. Sowohl Statistiken über erfolgreiche und fehlgeschlagene Tests als auch Code Coverage werden sichtbar gemacht.

SonarLint für Visual Studio

Ich bin sicher, Sie als Entwicklerin oder Entwickler wünschen sich, dass Sie nicht erst vom Build-Server auf Unschönheiten im Code aufmerksam gemacht werden. Besser wäre es, die Warnungen und Fehler schon in Visual Studio zu sehen und vielleicht sogar Code Fixes dafür angeboten zu bekommen. Genau diese Funktion wird durch die Visual-Studio-Erweiterung SonarLint for Visual Studio geboten. Sie können sie mit wenigen Klicks über Extensions and Updates installieren.

SonarLint erweitert unter anderem den Visual Studio Team Explorer. Sie erhalten einen neuen Menüpunkt SonarQube, mit dessen Hilfe Sie Ihr Projekt mit dem SonarQube-Server verbinden können. Ihr Projekt wird dadurch wie folgt verändert (Abb. 7): Es werden NuGet-Pakete für die Codequalitätsprüfung hinzugefügt. Sie enthalten die Analyzer, die mithilfe von Roslyn Ihren C#-Quellcode prüfen.

Ruleset-Dateien werden zu Ihrem Projekt hinzugefügt. Sie legen fest, welche Prüfungen aktiv sind und welcher Schweregrad den jeweiligen Fehlertypen zugewiesen wird (z. B. Warning, Error). Die initialen Rulesets werden vom SonarQube-Server übernommen, damit die Einstellungen zusammenpassen.

Abb. 7: Mit SonarQube-Server verbundenes C#-Projekt

Abb. 7: Mit SonarQube-Server verbundenes C#-Projekt

Wenn Sie nach der Verbindung Ihres Projekts mit SonarQube kompilieren, werden Sie die SonarQube-Warnungen und -Fehler genauso sehen, wie Sie es vom normalen C# gewohnt sind. SonarQube-Warnungen erkennt man am vorangestellten „S“ (Abb. 8). Visual Studio bietet direkt aus der IDE auch die Möglichkeit, nach den Fehlertexten zu suchen, falls man sich nicht darüber im Klaren ist, warum SonarQube einen Einwand gegen ein gewisses Codekonstrukt hat.

Abb. 8: SonarQube-Warnungen in Visual Studio

Abb. 8: SonarQube-Warnungen in Visual Studio

Fazit

SonarQube ist eine echte Bereicherung für C#-Entwicklungsteams, die Wert auf Softwarequalität legen. Die drei für mich wichtigsten Eigenschaften sind:

  1. Die Ergebnisse der Qualitätsanalysen sind über die Weboberfläche einer größeren Zielgruppe zugänglich.
  2. Analyseergebnisse für unterschiedliche Programmiersprachen (z. B. C# für das Backend, JavaScript für das Frontend) sind über die gleiche Plattform abfragbar.
  3. Die historische Speicherung der Daten macht sichtbar, ob Fortschritte in Sachen Codequalität gemacht wurden.

Installation und Wartung von SonarQube sind für Microsoft-orientierte Teams möglicherweise eine Herausforderung, da der Server auf Java-Basis läuft. Dieses Problem kann jedoch leicht umgangen werden, indem man wie erwähnt die fertigen Docker-Images verwendet. In Kombination mit dem vorgefertigten Ubuntu-Image und der Docker-Extension in Azure wird der Aufbau des SonarQube-Servers zu einer leichten Übung.

Alles in allem ist es meiner Ansicht nach sehr zu begrüßen, dass Microsoft sich bei SonarQube engagiert. Hoffen wir, dass dieses Engagement nachhaltig ist und die Analyzer immer besser und die Code Fixes immer mehr werden.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -