Code Coverage

Wirklich alles testen: Testabdeckung messen mit EclEmma

Marc Hoffmann

(c) Shutterstock / Shai_Halud

Testgetriebene Softwareentwicklung hat sich als Standard bei modernen Softwareprojekten durchgesetzt. Dabei werden für alle zu entwickelnden Features parallel automatisierte Regressionstests entwickelt. Folgen Entwickler dabei dem „Test First“-Ansatz, werden die Tests grundsätzlich vor dem eigentlichen Anwendungscode entwickelt. Eine konsequente Anwendung dieser Technik hilft, Quellcode sauber zu strukturierten, und führt zu korrekten und minimalen Implementierungen.

Die Tests basieren bei testgetriebener Softwareentwicklung (engl. Test-driven Development, TDD) typischerweise auf Unit-Test-Frameworks wie JUnit [1] oder TestNG [2] und sollten während der Entwicklung regelmäßig ausgeführt werden – zumindest vor jedem Commit in das gemeinsame Sourcecode-Repository. Glücklicherweise unterstützt die Eclipse-Entwicklungsumgebung Anwender dabei. Die Tests lassen sich direkt inklusive grafischer Rückmeldung ausführen.

Während bestehende Tests eine gute Absicherung der dadurch getesteten Funktionalität darstellen, haben wir keine Garantie, dass die komplette Codebasis auch wirklich getestet ist. Insbesondere über Jahre gewachsene Softwareprojekte weisen häufig keine oder nur eine sehr eingeschränkte Testabdeckung auf. Hier kommen Werkzeuge zur Ermittlung der Testabdeckung (engl. Code Coverage) zum Einsatz: Diese ermitteln während der Testausführung, welche Teile der Codebasis durch die Tests auch tatsächlich ausgeführt wurden. Im Umkehrschluss lassen sich damit die ungetesteten Teile eines Softwareprojekts ermitteln. Zusammenfassend gesagt überprüfen die automatischen Regressionstests die Korrektheit der Implementierung, während mithilfe der Testabdeckung die Vollständigkeit der Regressionstests gemessen wird (Abb. 1).

hoffmann_eclemma_1

Abb. 1: Die automatischen Regressionstests überprüfen die Korrektheit der Implementierung, während mithilfe der Testabdeckung die Vollständigkeit der Regressionstests gemessen wird

Plug-in ermittelt Testabdeckung

Um die vorhandene Testabdeckung einfach und schnell direkt in Eclipse ermitteln zu können, wurde 2006 das Eclipse-Plug-in EclEmma [3] geschaffen und unter der Eclipse Public License (EPL) zur freien Nutzung zur Verfügung gestellt. Das Plug-in hat sich schnell in der Java-Entwicklergemeinschaft als Standarderweiterung für Eclipse durchgesetzt und wurde zweimal mit einem Eclipse-Community-Award ausgezeichnet; 2007 als Finalist und 2008 als Winner. Die jeweils aktuellste Version von EclEmma lässt sich von der Updatesite http://update.eclemma.org/ oder aber über den Eclipse Market Place [4] installieren. Das Plug-in unterstützt alle Eclipse-Versionen ab 3.5. Nach der Installation ist die einzige auf den ersten Blick erkennbare Erweiterung in Eclipse ein neuer Ausführungsmodus mit dem Namen „Coverage“, der sich zu den bekannten Ausführungsmodi „Run“ und „Debug“ gesellt (Abb. 2).

hoffmann_eclemma_2

Abb. 2: Die erste erkennbare Erweiterung durch das Plug-in EclEmma ist der Ausführungsmodus „Coverage“

 

Startet man eine beliebige Java-Anwendung im Coverage-Modus, werden während der Ausführung Informationen über die ausgeführten Codeteile gesammelt. Das Ergebnis wird automatisch beim Beenden der Anwendung, zum Beispiel nachdem alle Testfälle ausgeführt wurden, in der durch das Plug-in hinzugefügten Coverage-View angezeigt. Auf Projektebene bis hinunter zu einzelnen Java-Methoden lassen sich verschiedene Abdeckungsmetriken ermitteln: Bytecode-Instruktionen, Verzweigungen, zyklomatische Komplexität, Zeilen, Methoden und Klassen (Abb. 3).

hoffmann_eclemma_3

Abb. 3: Das Ergebnis wird automatisch beim Beenden der Anwendung in der neu hinzugekommenen Coverage-View angezeigt

 

Zusätzlich hängt sich EclEmma in die Java-Source-Editoren und hebt den Ausführungsstatus dort farblich hervor: Vollständig ausgeführte Zeilen sind grün markiert. Gelb sind teilweise ausgeführte Zeilen, zum Beispiel im Fall von Verzweigungen innerhalb einer Zeile. Rot hinterlegte Zeilen schließlich wurden überhaupt nicht ausgeführt und benötigen vermutlich zusätzliche Tests. Kleine farbige Rauten am linken Rand des Editors zeigen mit demselben Farbcode den Ausführungsstatus von Verzweigungen in Zeilen, die zum Beispiel if- oder switch-Anweisungen enthalten (Abb. 4).

hoffmann_eclemma_4

Abb. 4: EclEmma hängt sich in die Java-Source-Editoren und hebt den Ausführungsstatus dort farblich hervor

 

Oft übersehene Funktionen nutzen

Da EclEmma in der Standardverwendung weitgehend selbsterklärend ist, gibt es einige nützliche Funktionen, die oft übersehen werden. Im Standardfall ermittelt EclEmma die Codeabdeckung erst, nachdem sich das Java-Programm beendet hat. Es ist jedoch gar nicht notwendig, das Programm zu beenden, um die Metriken zu erhalten: In der Toolbar der Coverage-View gibt es einen Button „Dump Coverage Data“, der es erlaubt, Abdeckungsdaten jederzeit zu berechnen.

Abhängig vom verwendeten Testszenario kann es sein, dass die getestete Anwendung gar nicht innerhalb von Eclipse ausgeführt wird, sondern zum Beispiel auf einem Server installiert ist. Über den Import-Wizard „Coverage Session Import“ können Abdeckungsdaten von einem beliebigen Java-Prozess abgeholt werden, für den ein JaCoCo-Agent [5] konfiguriert ist. Das ist die Technologie im Herzen von EclEmma. Viele Projekte haben verschiedene Testszenarien, wie Unit oder Integrationstests, die nacheinander in verschiedenen Java-Prozessen ausgeführt werden. Wenn für diese jeweils Abdeckungsdaten gesammelt wurden, lassen sie sich mithilfe des „Merge Sessions“-Button in der Coverage-View zu einer einzigen Abdeckungsanalyse zusammenführen.

Während die direkte Darstellung der Codeabdeckung in der Entwicklungsumgebung sehr praktisch ist, mag es manchmal hilfreich sein, die Daten auch in anderen Formaten zu speichern. Dazu erlaubt der „Coverage“-Export-Wizard zum Beispiel, einen navigierbaren HTML-Report zu extrahieren. Weitere unterstützte Formate sind XML und CSV. Um mehr über diese Funktionen und weitere herauszufinden, ist die mit dem Plug-in ausgelieferte Onlinehilfe [6] eine gute Referenz.

Das Herz von EclEmma

Ursprünglich wurde EclEmma als Eclipse-Integration für das Code-Coverage-Werkzeug EMMA [7] entwickelt. Die Wartung und Weiterentwicklung von EMMA wurde jedoch bereits vor vielen Jahren aufgegeben. Somit bietet EMMA keine Unterstützung für die heute aktuellen JDKs, und es fehlen wichtige Feature wie Verzweigungsabdeckung. Aus der Not heraus wurde im Rahmen von EclEmma eine eigenständige Code-Coverage-Bibliothek JaCoCo (Java Code Coverage) entwickelt [8]. Trotz des Namens basiert EclEmma seit dem Release der Version 2.0 im Jahre 2012 vollständig auf JaCoCo.

JaCoCo ist als eigenständiges Werkzeug verfügbar und somit eine sinnvolle Ergänzung zum Eclipse-Plug-in EclEmma, da es sich aufgrund zahlreicher Integrationsmöglichkeiten (Ant, Maven, Gradle, SBT) gut in die Werkzeugkette einfügt. Die Abdeckungsanalyse mit JaCoCo lässt sich darüber hinaus auch in „Continuous Inspection“-Plattformen wie SonarQube [9] zur Überwachung der Projektqualität integrieren.

Fazit

Onkel Bob, Robert Martin, hat es wie folgt ausgedrückt: „Ungetesteter Code ist die dunkle Materie der Software. Offenbar weil er 90 Prozent des Softwareuniversums ausmacht.“ Verantwortungsvolle Softwareentwickler müssen solch dunkle Materie in ihren Projekten verhindern. Dafür ist eine kontinuierliche Überwachung mit Codeabdeckungstools in der Entwicklungsumgebung und Continuous Integration Builds unabdingbar.

Verwandte Themen:

Geschrieben von
Marc Hoffmann
Marc Hoffmann
Marc Hoffmann hat das EclEmma-Eclipse-Plug-in entwickelt und ist auch Projektleiter des JaCoCo-Projekts. Neben seinem Open-Source-Engagement arbeitet er als Softwarearchitekt für Systeme zur Steuerung des Eisenbahnverkehrs. Marc Hoffmann ist CTO bei der mtrail GmbH in der Schweiz. Twitter Handle: @marcandsweep
Kommentare

Hinterlasse einen Kommentar

1 Kommentar auf "Wirklich alles testen: Testabdeckung messen mit EclEmma"

avatar
400
  Subscribe  
Benachrichtige mich zu:
Felix
Gast

Tests können in der Praxis niemals die Korrektheit eines Programms nachweisen. Sie können nur Fehler nachweisen. Wäre das anders hätten wir in der IT nicht so viel mit Bugs zu kämpfen 😉

Man sollte auch nicht vergessen, dass Eine 100%ige Testabdeckung noch keine guten Tests Garantiert. Ich habe schon Projekte gesehen, die 100% Testabdeckung ohne assert Anweisung in den meisten Tests aufweisen konnten. Testabdeckung zu messen ist gut und wichtig, aber man sollte sich nicht allein auf diese Metrik verlassen 🙂