Alle Beiträge, jStage Platform, Technologien & Entwicklung

Doppelt hält besser – Code Reviews mit Gerrit

Code Reviews mit Gerrit

Wer hat sich nicht schon mal über Softwarefehler geärgert, sei es am Fahrkartenautomat, bei der Bank oder bei der täglichen Büroarbeit.  Je komplexer eine Software, desto höher ist die Wahrscheinlichkeit, dass diese Fehler beinhaltet, die den Benutzer frustrieren. Dieser Blogbeitrag beschäftigt sich mit einer Möglichkeit, Fehler frühzeitig zu erkennen und somit vor dem Deploy zu beheben: Code Reviews.

Code Qualität

Bevor wir zu den Code Reviews an sich kommen, ein paar Worte zum Thema “Code Qualität”. Man hört und liest sehr häufig, dass es wichtig und notwendig ist, Quellcode mit hoher Qualität zu schreiben. Doch wieso ist diese hohe Qualität so wichtig, speziell im Umfeld produktiver und profressioneller Software?

Wartbarkeit stellt hier ein sehr wichtiges Kriterium dar. Professionelle Software wird meist über viele Jahre hinweg (weiter) entwickelt und gepflegt. Je höher die Qualität, desto leichter ist die Wartbarkeit bzw. das sukkzessive Erweitern der Software. An dieser Stelle kommt ein weiterer wichtiger Faktor ins Spiel: Lesbarkeit des Codes. Dazu gehören speziell die sprechende Benennung von Variablen und Methoden, klare Strukturierung und Kommentare. Je höher die Lesbarkeit, desto schneller versteht auch ein anderer Entwickler den Code. Durch Kommentare können spezielle Design-Entscheidungen oder Lösungen ebenfalls vermittelt werden. Zu beachten ist bei Kommentaren jedoch, dass diese nicht überhandnehmen. Im Idealfall spricht der Code für sich selbst und der Kommentar gibt nur ergänzende Hinweise.

Ein weiteres Kriterium hoher Code Qualität ist das DRY – Prinzip (Don’t repeat yourself). Dies bedeutet, dass man keine Codestellen dupliziert, sondern wiederverwendbar in Methoden oder andere Konstrukte auslagert. Hierdurch wird ebenfalls die Wartbarkeit des Codes erhöht. Auch können Fehler vermieden werden, da, bei Bedarf, nicht an mehreren Stellen gleiche Änderungen durchgeführt werden müssen.

Um die eben angesprochenen Kriterien kontinuierlich zu erfüllen und “schlechten” Quellcode zu verbessern, stellen Code Reviews im Entwicklungszyklus ein wichtiges Puzzleteil dar. Um diese geht es im folgenden Abschnitt.

Code Reviews

Es gibt unterschiedliche Gründe Code Reviews in einem Team ein- und durchzuführen. Die wichtigsten sind “Verteilung von Wissen im Team” und “frühes Aufdecken von Inkonsistenzen bzw. Fehlern”. Der Ablauf eines Code Reviews kann sich, je nach Komplexität der Änderung,  pro Task unterscheiden. Im Normalfall sind Reviews von mindestens einem andereren Team-Mitglied durchzuführen. Der grundlegende Ablauf ist in Abbildung 1 skizziert.

Ein Entwickler programmiert eine Funktionalität. Anschließend übergibt er diese dem Reviewer (idealerweise auch ein Entwickler) zur Überprüfung. Im Idealfall kann der Reviewer diese ohne Beanstandung in den Master-Branch übernehmen. Andernfalls gibt er den Task an den Entwickler zurück, sodass dieser nachbessern kann.

Bei besonders komplexen Funktionalitäten kann der Entwickler dem Reviewer auch seinen Lösungsansatz erläutern. Man könnte dies als “Pair Review” bezeichnen.
Ein weiterer Sonderfall ist, dass die Änderung an einem Task so minimal ist, dass kein Review notwendig ist. Hier kann der Entwickler seine Änderungen direkt in den master – Branch übernehmen. Dies sollte jedoch die absolute Ausnahme sein und auch nicht unter Umgehung des Review-Systems geschehen.

Code Review - GrundprozessAbb. 1: Code Review – Grundprozess

Ablauf des Reviews

Ein Code Review besteht grundlegend aus zwei Phasen: “Technisches/Fachliches Review” und “Feedback geben”.

In Phase 1 wird der Quellcode überprüft, ob Richtlinien (DRY – Prinzip, Bezeichnungen, …) und Architektur eingehalten wurden und gegen die Anforderungen getestet, ob diese erfolgreich umgesetzt wurden. Stellen, an denen eine Verbesserung durchgeführt werden kann, können vom Reviewer im Review – Tool (z. B. Gerrit) entsprechend markiert und kommentiert werden.

In der Feedback-Phase gilt es, dem Entwickler ein Feedback zu seinem Review zu geben. Die zu beanstandenden Punkte sind hierbei objektiv und sachlich zu beschreiben. Wichtig ist, dass ein Review nicht als persönliche Kritik am Entwickler aufzunehmen ist. Ziel ist, die Code Qualität zu steigern und den Entwickler für definierte Vorgehensweisen und Richtlinien zu sensibilisieren oder ihn auf unbekannte Codestellen hinzuweisen (z. B.  ein bestimmtes Util, in dem eine neu entwickelte Funktionalität bereits vorhanden ist -> DRY – Prinzip). Hilfreich ist hierbei, dem Review eine Note zu vergeben, dass der Entwickler mitbekommt, ob er “nur” sauberer arbeiten muss oder ob der gesamte Lösungsansatz der Falsche war. Somit kann der Reviewer auch mitgeben, ob es sich um Kleinigkeiten oder schwerwiegende Beanstandungen handelt.

Nach einem erfolgreichen Review kann der Reviewer die Änderungen in den Master-Branch übernehmen und den Task schließen.

Grenzen von Code Reviews

Trotz aller Vorteile des  “4 Augen Prinzips” haben Code Reviews auch Grenzen. So ist der Kosten/Nutzen – Faktor zu berücksichtigen. Es gibt zwar keinen fixen Faktor, ab dem sich ein Review nicht mehr lohnt, jedoch sollte der Aufwand für Reviews berücksichtigt werden. Allgemein ist festzuhalten, dass sich auch in einem Review nicht jede Kleinigkeit finden und beheben lässt. Grundlegende Fehler lassen sich beheben und damit ist jede Minute Review wertvoll und sinnvoll investiert. Auch ist es für den Reviewer, speziell bei sehr komplexen Änderungen, eine Herausforderung, den Gedankengang und Lösungsansatz des Entwicklers komplett nachzuvollziehen. Hier muss auch darauf vertraut werden, dass sich der Entwickler Gedanken gemacht hat und es sollte keinesfalls versucht werden, eine Funktionalität nochmal zu konzipieren und neu zu entwickeln. Allgemein lässt sich festhalten, dass es ein ausgewogenes Verhältnis zwischen Entwicklungs- und Reviewzeit geben sollte. Andernfalls müsste man entweder den Lösungs- oder den Reviewansatz überdenken.

Gerrit im Entwicklungszyklus

Gerrit ist ein unter der Apache License 2.0 stehendes Review-Tool für das Versionsverwaltungssystem git. Es bietet die Möglichkeit über eine Weboberfläche Code Reviews durchzuführen. Es können auch mehrere Reviewer parallel an einem Review arbeiten und ihre Bewertung abgeben. Dabei kann konfiguriert werden, wann ein Review als “erfolgreich” gilt.

Gerrit - ÜbersichtAbb. 2: Gerrit – Übersicht

Wie in Abbildung 2 zu sehen, bildet Gerrit  um das git-Repository bildlich gesprochen eine Hülle und kapselt es, je nach Einstellung, vor direktem pushen in Branches. Die Entwickler holen sich aus dem produktiven Repository den aktuellen Stand, führen ihre Änderungen durch und pushen diese in das Review Repository (sog. Change Request). Der/Die Reviewer holen sich diesen Stand aus dem Review Repository, überprüfen die Änderung und geben anschließend ihr “ok” bzw. weisen den Change zurück. Wird der Change zurückgewiesen, kann der Entwickler ein weiteres Patch Set hochladen, um Nachbesserungen durchzuführen. Nach der Annahme des Changes wird der Code – im besten Fall – automatisch von Gerrit in das produktive Repository übertragen.

Im jStage Umfeld wird Gerrit als Review Tool seit der Migration der Versionsverwaltung von SVN zu git seit ca. 2 Jahren erfolgreich eingesetzt. Nach einer kurzen Eingewöhnungsphase und Umstellung des Entwicklungszyklus, bettet sich Gerrit sehr gut in diesen ein und stellt auch kein Hindernis bei der Entwicklung dar.

Fazit

In diesem Beitrag wurde ein kurzer Überblick über Code Reviews und wie diese im jStage Entwicklungszyklus eingebettet sind gegeben. Es wurde gezeigt, dass es sich bei Reviews um sinnvoll investierte Zeit handelt, speziell um Fehler frühzeitig zu erkennen und das Wissen über Änderungen im Quellcode im Team zu verteilen. Auch bieten Code Reviews die Möglichkeit, neue Entwickler einzuarbeiten und sie auf für sie unbekannte Code Stellen aufmerksam zu machen.

Im Umfeld professioneller Softwareentwicklung sind Code Reviews ein unverzichtbares Puzzleteil, um die Qualität von Software zu steigern bzw. hoch zu halten.